1、作用域 :函数外的变量的作用域为全局作用域(命名空间对应全局命名空间),函数体内的变量(未用global声明)的作用域为内部作用域(对应局部命名空间);函数体内的变量称为局部变量
>>> x = 1 ###x的作用域为全局作用域,对应全局命名空间
>>> def foo():
x = 42 ###x的作用域为局部作用域 ,对应局部命名空间,具体的作用域只在函数体内;局部命名空间中的x指向42
return x
>>> x
1
>>> foo() ###调用foo函数的时候,局部命名空间就被创建,仅作用于函数内代码块
42
>>> x ###调用的全局作用域(全局命名空间)中的x指向的值,所以x=1
1
2、Shadowing屏蔽的问题;如果函数体内的局部变量和全局变量的名字相同,在函数体内引用全局变量的话,局部变量会把全局变量屏蔽掉
>>> def combine(parameter):
external = 'berry'
print(parameter+external)
>>> external = 'Sunshine'
>>> #想生成'parameter+'Sunshine''
>>> combine('you are my ')
you are my berry ###这个结果并不是我们期待的结果,因为局部变量和全局变量的名字一样,所以局部变量把全局变量屏蔽了
3、globals()函数,无参数,将获取全局变量的字典类型,使用方法 globals()['全局变量名'] 返回全局变量对应的值;修改上面的函数
>>> def combine(parameter):
external = 'berry'
print(parameter+globals()['external'])
>>> external = 'Sunshine'
>>> combine('you are my ')
you are my Sunshine
4、函数内重新绑定全局变量(指向新的内容),如果函数有必要改变全局变量,使用global 变量名;用global声明 函数体内的变量为全局变量
>>> x = 1
>>> def change_global():
global x
x = x+1
>>> change_global()
>>> x
2
5、嵌套作用域,一个函数内嵌套了另一个函数,外层函数返回内层函数(内层函数未被调用只是返回);内层函数是可以访问外层函数的变量的,这个就叫嵌套作用域;
例子:
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor)####外层函数multiplier的变量factor,被内层函数multiplyByFactor引用了
return multiplyByFactor###外层函数返回内层函数
类似multiplyByFactor函数,存储于一个封闭的作用域的行为叫做闭包(因为它引用的变量都在函数体内或者外层函数内,如果factor为全局变量,则它就不是闭包)
查看一个函数是否是闭包用:函数.__closure__
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor)
print(multiplyByFactor.__closure__)###双下划线
return multiplyByFactor
>>> multiplier(2)
(<cell at 0x000001A961B4AEB8: int object at 0x00007FFE82BBE370>,) ##显示cell说明函数multiplyByFactor是闭包
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B79F28>###这个返回值只说明multiplier内嵌了函数multiplyByFactor,并不表示multiplyByFactor是闭包
非闭包嵌套函数
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*number2)###未引用外层函数的变量
print(multiplyByFactor.__closure__)
return multiplyByFactor
>>> number2 =3
>>> multiplier(2)
None ###说明multiplyByFactor函数不是一个闭包函数,因为它引用的变量是自己的变量和全局变量,未引用外层函数变量
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B92048>
>>> def multiplier(factor):
def multiplyByFactor(number):
return(number*factor*number2)###引用自身变量、外层函数变量、全局变量也不是闭包
print(multiplier.__closure__)
return multiplyByFactor
>>> number2 =3
>>> multiplier(2)
None
<function multiplier.<locals>.multiplyByFactor at 0x000001A961B79F28>
nonlocal函数可以使内部函数重新对外层函数变量进行重绑定
>>> def counter():
counter = 0
def do_nonlocal():
nonlocal counter
counter+=1
return counter
return do_nonlocal
>>> ct = counter()
>>> print(ct())
1
>>> print(ct())
2
>>> print(ct())
3
>>> ct = counter() ###counter=0被重定向为1
>>> print(ct())
1
注意:如果内层函数变量名与外部函数变量名重复,外部函数变量名会覆盖内层函数变量名
提示:Inspection info: This inspection detects shadowing names defined in outer scopes.
def scope_test(): def func_local(): ##Inspection info: This inspection detects shadowing names defined in outer scopes. parameter = 'local parameter' def statement_nonlocal(): nonlocal parameter parameter = 'nonlocal parameter' def statement_global(): global parameter parameter = 'global parameter' parameter = 'out scope parameter' func_local() print('After local assignment:',parameter) statement_nonlocal() print('After nonlocal assignmet:',parameter) statement_global() print("After global assignment:",parameter) if __name__ == '__main__': scope_test() print('now the parameter is:',parameter)