一、名称空间和作用域
1.全局名称空间(名称空间、命名空间):
py文件运行时代码从上之下依次执行,看到一个变量就会将这个变量与对应值的内存地址的关系存到名称空间里,代码要运行时(print时)从名称空间里找变量与对应值的内存地址,通过内存地址找到对应的值。
2.局部名称空间(临时名称空间):
函数名放在内存地址里,当执行函数时,会在内存中开辟一个临时名称空间 ,存放函数体内的所有变量与值的关系。随着函数的执行完毕,临时空间自动关闭。
3.内置名称空间:所有的内置函数等存储的空间。
加载顺序:内置名称空间---->全局名称空间---->(函数执行时)局部名称空间
取值顺序:(函数执行时)局部名称空间--->全局名称空间---->内置名称空间
4.全局作用域:包含全局名称空间,内置名称空间,在整个文件的任意位置都能被引用,全局有效。
局部作用域:局部名称空间,只在局部范围内有效。
5.内置函数
globals:将全局名称空间的所有变量放在一个字典里。
lacals:将局部名称空间里的变量放在一个字典里。
6.关键字
global作用:
1)在局部名称空间内声明一个全局变量。
def func1(): global name name='老男孩' print(name) func1() print(name) 执行结果: 老男孩 老男孩
2)在局部名称空间内改变一个全局变量。
name='wusir' def func1(): global name name='老男孩' print(name) func1() print(name) 执行结果: 老男孩 老男孩
nonlocal(python2中没有):
1.不能修改全局作用域。
a=4 def func1(): nonlocal a a=5 print(a) func1() print(a) 报错#a是全局
2.在局部作用域中,对父级作用域(后者更外层的作用域非全局作用域)的变量进行引用和修改,并且引用的哪层从哪层及以下的变量全部发生改变。
a=4 def func1(): b=6 def func2(): nonlocal b #从这层起对b进行修改 b=666 print(b) func2() print(b) func1() 执行结果: 666 666
二、函数的嵌套
函数调用时执行
代码从上至下依次执行,调用函数时函数里面从上之下依次执行
def f1(): print('in f1') def f2(): print('in f2') f2() f1() 执行结果: in f1 in f2
def f1(): #print('in f3') def f2(): #print('in f1') def f3(): #print('in f2') print('in f3') print('in f2') f3() print('in f1') f2() f1() 执行结果: in f1 in f2 in f3
三、函数名的本质
函数名是函数的名字,本质是变量(特殊的变量),函数名()表示执行此函数。
1.单独打印函数名返回函数的地址。
def func1(): print(666) print(func1) 执行结果: <function func1 at 0x000000D735492400>
2.函数名的赋值。
def func2(): print(666) f=func2 print(f()) 执行结果: 666 None
3.函数名可以作为容器类数据的元素。
def f1(): print(11) def f2(): print(22) def f3(): print(33) l1=[f1,f2,f3] for i in l1: i() l1=[] for i in range(1,4): l1.append('f'+str(i)) print(l1) for i in l1: eval(i)()
4.函数名可以作为参数。
a=1 def f1(x): print(x) f1(a) 执行结果: 1
5.函数名可以作为函数的返回值。
def f11(x): return x ret=f11(5) print(ret) 执行结果: 5
四、闭包
闭包就是内层函数对外层函数(非全局)变量的引用。
def wraaper1(): name='guo' def inner(): print(name) inner() print(inner.__closure__) wraaper1() 执行结果: guo (<cell at 0x00000073DFFA7228: str object at 0x00000073DFF8CDF8>,)
当函数开始执行时,如果遇到了闭包,它有一个机制,它会永远开辟一个内存空间,将闭包中的变量等值放在其中,不会随着函数的执行完毕而消失。
name='老男孩' def wraaper2(n): def inner(): print(n) inner() print(inner.__closure__) wraaper2(name) 执行结果: 老男孩 (<cell at 0x0000007DC1777228: str object at 0x0000007DC1773260>,)