python函数-函数进阶
一、命名空间和作用域
1.命名空间
内置命名空间 —— python解释器
就是python解释器一启动就可以使用的名字存储在内置命名空间中
内置的名字在启动解释器的时候被加载进内存里
全局命名空间 —— 我们写的代码但不是函数中的代码
是在程序从上到下被执行的过程中依次加载进内存的
放置了我们设置的所有变量名和函数名
局部命名空间 —— 函数
就是函数内部定义的名字
当调用函数的时候 才会产生这个名称空间 随着函数执行的结束 这个命名空间就又消失了
在局部:可以使用全局、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字,但是不能用局部中使用
在内置:不能使用局部和全局的名字的
在正常情况下,直接使用内置的名字
当我们在全局定义了和内置名字空间中同名的名字时,会使用全局的名字
当我自己有的时候 我就不找我的上级要了
如果自己没有 就找上一级要 上一级没有再找上一级 如果内置的名字空间都没有 就报错
多个函数应该拥有多个独立的局部名字空间,不互相共享
2.作用域
全局作用域:内置命名空间、全局命名空间
局部作用域:局部命名空间
3.global关键字
对于不可变的数据类型,在局部可以查看全局作用域中的变量,但是不能修改,如果想在局部作用域中对全局作用域的不可变数据类型变量进行修改,需要在局部开始加上global声明
x = 1 # 全局作用域的不可变数据类型变量x def func(): global x # 在局部作用域中对其进行声明 x = 2 # 声明后则可以在局部作用域中对其进行修改操作 func() print(x) # 局部作用域将全局作用域的不可变数据类型变量修改后,在全局作用域中打印,其值被修改
4.locals()、globals()函数
①globals():输出全局作用域的所有变量
②locals():输出当前作用域的所有变量
a = 1 def func(): a = 666 print('函数内部的locals:'+str(locals())) func() print('函数外部的globals:'+str(globals())) print('函数外部的locals:'+str(locals())) >>> 函数内部的locals:{'a': 666} >>> 函数外部的globals:{'__doc__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000000653EF0>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, '__spec__': None, '__author__': 'Elijah', '__file__': 'D:/python_fullstack_s9/day10/practice.py', '__date__': '2017/12/27 8:33', 'func': <function func at 0x000000000070E6A8>, 'a': 1, '__package__': None} >>> 函数外部的locals:{'__doc__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000000000653EF0>, '__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>, '__cached__': None, '__spec__': None, '__author__': 'Elijah', '__file__': 'D:/python_fullstack_s9/day10/practice.py', '__date__': '2017/12/27 8:33', 'func': <function func at 0x000000000070E6A8>, 'a': 1, '__package__': None}
③global关键字
a = 1 def func(): global a a = 666 func() print('此时a的值:' + str(a)) >>> 此时a的值:666
④nonlocal和global
global---在局部声明一个全局变量
nonlocal--在局部声明最近的上一层局部中的变量
nonlocal 1.对全局无效 2.对局部,也是对最近的一层有影响 3.只能用于局部变量,找上层中离当前函数最近一层的局部变量 4.声明了nonlocal的内部函数的变量,修改会影响到离当前函数最近的一层的局部变量
a = 0 def func(): #a = 1 def inner(): a = 2 def inner2(): nonlocal a inner2() inner() func()
5.函数的嵌套
def outer(): print('this is outer!') def inner(): print('this is inner!') inner() outer()
6.作用域链
小范围用变量的时候,先从自己的命名空间查找,找不到就一层一层向外层找,知道找为止,找不到就报错
a = 1 def outer(): a = 1 def inner(): a = 2 def inner2(): nonlocal a #声明了一个上面第一层局部变量 a += 1 #不可变数据类型的修改 inner2() print('##a## : ', a) inner() print('**a** : ',a) outer() print('全局 :',a)
7.函数名的本质
①可以被赋值
②可以被当作容器类型的元素
③可以当作函数的参数和返回值
第一类对象(first-class object)指 1.可在运行期创建 2.可用作函数参数或返回值 3.可存入变量的实体
8.闭包
①内部函数调用对外部函数,还是嵌套函数称为闭包函数
def outer(): a = 1 def inner(): print(a) return inner inn = outer() inn()
②判断闭包函数的方法__closure__
#输出的__closure__有cell元素 :是闭包函数 def func(): name = 'eva' def inner(): print(name) print(inner.__closure__) return inner f = func() f() #输出的__closure__为None :不是闭包函数 name = 'egon' def func2(): def inner(): print(name) print(inner.__closure__) return inner f2 = func2() f2()