python 中函数的返回值、作用域及名称空间介绍

一、函数的返回值

  函数外部代码想要获取函数的执行结果,就可以在函数内部用return语句将结果返回。

def student(name,age,country="China"):
    print(name,age,country)
    if age>30:
        return True
    else:
        return False

student_stus = student("lilei",33)
if student_stus:
    print("too old to be a student")
else:
    print("注册成功")

  函数的返回值通过return语句进行返回,如果没有return语句,则函数的返回值默认为None,return语句可以返回数字、字符串、列表元组等多种数据类型,返回多个值时,以元组的形式返回。函数在执行到return语句后,就会停止并返回结果,并代表函数已经结束。

二、全局变量和局部变量及其作用域

  看如下代码:

name = "zhangsan"  # 定义全局变量
def change_name():
    name = "lisi"  #定义局部变量
    print("after change:",name)
change_name()
print("外边的name:",name)
结果:
after change: lisi
外边的name: zhangsan

  为什么在函数内部改变了name的值,在外边print的时候却没有改变呢。因为这两个name不是一个变量,一个是局部变量一个是全局变量。

  局部变量:在函数内部定义的变量称为局部变量,而在函数外程序刚开始就定义的变量称为全局变量。

  作用域的概念:作用域指的是变量的作用范围或有效范围,局部变量的作用域是定义该变量的函数,而全局变量的作用域是整个程序。

  变量的查找顺序是局部变量>全局变量,当全局变量与及局部变量同名时,在定义局部变量的函数内,局部变量起作用,在其他地方全局变量起作用,所以在函数内部是无法修改全局变量的。

name = "zhangsan"
name1 = "wangwu"
def change_name():
    name1 = "lisi"
    print(name, name1)  
change_name()
结果:zhangsan lisi  # name在change_name函数内部没有,找不到,只能到函数外部找;而name1在change_name函数内部找到了,所以不会再到函数外部去找。

  如何在函数内部声明全局变量呢

name = "lisi"
def change_name():
    global name
    name = "wangwu"
    print("局部:",name)
change_name()
print("全局:",name)
结果:
局部: wangwu
全局: wangwu

  通过global 关键字可以将局部变量声明为全局变量,这样就能对其进行修改。

扫描二维码关注公众号,回复: 9701929 查看本文章

  传递列表、字典、集合等会发生什么现象;

dic = {
    'name':'zhangsan',
    'age':18,
    'hobby':'study'
}
lis = ['lisi','wangwu']
def change_data(info,people):
    info['hobby']='学习'
    lis.append('zhangsan')
change_data(dic,lis)
print(dic,lis)
结果:
{'name': 'zhangsan', 'age': 18, 'hobby': '学习'} ['lisi', 'wangwu', 'zhangsan']

  从结果可以看到,函数内部也将函数外部的字典和列表等全局变量改变了,这是为什么呢?因为程序只是把dic和lis的内存地址给了change_data函数,但dic和lis的元素均有自己的内存地址,把dic 和 lis比作鱼缸,里面的元素比作鱼缸里的鱼,这个鱼缸本身你不能变,但是里面的鱼可以。相当于只是传了一个对这个dic的引用关系给到函数的形参。这样做是为了节省内存空间,如果dic中的内容比较多,传一次函数就要复制一份新的数据,那么效率就太低了。

 三、名称空间

  名称空间,又称name space,顾名思义就是存放名字的地方,存什么名字呢,变量名。比如 x= 1, 数据1存放在内存里,那么名字x存放在哪里呢?名称空间正式存放名字x 与 1 绑定关系的地方。

  python里面有很多名称空间,他们相互之间互不干扰,不同空间中的两个相同名字的变量之间没有什么联系。

  名称空间有四种:Locals、Enclosing 、Global 和 Builtins

  locals: 函数内部的名称空间,一般包括函数的局部变量以及形式参数。

  enclosing : 在嵌套函数中,外部函数的名称空间,若fuc2嵌套在func1中,对func2来说,func1的名称空间就是enclosing.

  globals: 当前模块的空间,模块就是一些py文件,也就是说,globals类似于全局变量。

  builtins: 内置模块空间,也就是内置变量或者内置函数的名称空间。

  不同的变量作用域不同,就是由这个变量所在的名称空间决定的。

  不同名称空间的作用域的查找顺序:当程序引用某个变量名时,就会从当前名字空间开始搜索,搜索顺序规则便是:LEGB。即locals ——>

enclosing ——>enclosing ——>globals ——>builtins。一层一层查找,找到了之后,便停止搜索,如果没有找到,则抛出NameError的异常。

level = "L1"
n = 1
name = "zhangsan"
def func():
    level = "L2"
    n = 2
    print("func:", locals(), n)
    def outer():
        level = "L3"
        n = 3
        print("outer:", locals(), n)
        def inner():
            level = "L4"
            print("inner:", locals(), n, name)
        inner()
    outer()
func()
print('globals:', 'level:', level, 'n:', n, 'name:',name)
结果:
func: {'level': 'L2', 'n': 2} 2
outer: {'level': 'L3', 'n': 3} 3
inner: {'level': 'L4', 'n': 3} 3 zhangsan
globals: level: L1 n: 1 name: zhangsan

猜你喜欢

转载自www.cnblogs.com/feixiangshuoshuo/p/12450357.html