函数进阶
1、命名空间
①内置命名空间: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
5、函数的嵌套
def outer():
print('this is outer!')
def inner():
print('this is inner!')
inner()
outer()
>>> this is outer!
>>> this is inner!
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、nonlocal函数
①nonlocal只能用于局部变量找上层中离当前函数最近一层的局部变量
②声明了nonlocal的内部函数的变量修改会影响到离当前函数最近一层的局部变量
③对全局无效
④对局部也只是对最近的一层有影响
a = 0
def outer():
# a = 1
def inner():
# a = 2
def inner2():
nonlocal a
print(a)
inner2()
inner()
# outer()
def func():
print(123)
8、函数名的本质:函数名本质上就是函数的内存地址
①可以被引用
②可以被当作容器类型的元素
③可以当作函数的参数和返回值
函数名是第一类对象
- 第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。
9、闭包
①内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
def outer():
a = 6
def inner():
print('a的值:'+str(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()