10:自定义函数时默认参数的陷阱、命名空间、和作用域
补充:
如果默认参数的值是一个可变数据类型,那么每一次调用函数的时候,如果不传值就公用这个数据类型的资源
def func(l=[]): l.append('1') print(l) func() func() func()
三次执行结果:
命名空间
命名空间有三种:
1、内置命名空间:-------python解释器
1、就是python一起动就可以使用的名字储存在内置明明空间中
2、内置的名字在启动解释器的时候被加载到内存里
2、全局命名空间:就是写的代码但不是函数中的代码
1、是在程序中从上到下被执行的过程中依次加载进内存里
2、放置了我们设置的所有变量名和函数名
3、局部命名空间:函数
1、就是函数内部定义的名字
2、当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间又消失了。
4、在局部:可以使用全局命名、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字
在内置:不能使用局部和全局命名空间中的名字
5、在正常情况下,直接使用内置的名字
当我们在全局定义了和内置名字空间相同的名字时,会使用全局的名字
当我自己有的时候,我就不找我的上级要了
如果自己没有,就找上级要,如果上级没有,就找内置空间要,如果内置空间没有,就会报错
多个函数应该有多个独立的局部名字空间,不互相共享(自己的老婆就是自己的)
6、作用域:全局作用域:作用在全局,全局和内置名字空间中的名字都属于全局作用域-----(globals:可以在函数内部用其声明,修改全局变量)
局部作用域:函数,局部命名空间中的名字属于局部作用域-------------------------(locals:可以修改函数内的上一级变量)
def func(): a=1 def func1(): a=2 print(a) func1() func()
1、对于不可变的数据类型,在局部只可查看全局作用域的变量,但是不能直接修改。
2、如果要修改,需要在程序一开始添加global声明。
3、如果在局部作用域(函数)内声明了一个global变量,那么这个变量在局部(函数内)的所有操作都会对全局的变量产生影响。
a = 1 def func(): global a a = 2 func() print(a)
#globals 永远打印全局的名字
#locals 输出什么 根据locals所在的
7、函数的嵌套调用:内部函数可以使用外部函数的变量
def the_max(x,y,z): #函数的嵌套调用 c = max(x,y) return max(c,z) print(the_max(1,2,3))
nonlocal :对于不可变数据类型的修改,nonlocal 声明了一个上面第一层局部变量
只能用于局部变量,找上层中离当前函数最近的一层的局部变量,声明了nonlocal的内部函 数的的变量修改会影响到离当前函数最近一层的局部变量。
对全局无效
对局部也只是对最近的一层有影响
8、关于变量名
def func():
print(123)
1)函数名是内存地址
2)函数名可以赋值:func2=func func()可以执行程序,也就是func的程序。
3)函数名可以作为容器类型的元素
l = [func,func2] #函数名可以作为容器类型的元素 print(l) for i in l: i()
4) 函数名可以作为函数的返回值
def wahaha(f): f() return f
5)函数名可以作为函数的参数
qqxing = wahaha(func)
qqxing()