参数的作用域

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)

原文地址:https://www.cnblogs.com/t-ae/p/10859442.html