參數的做用域

一、做用域 :函數外的變量的做用域爲全局做用域(命名空間對應全局命名空間),函數體內的變量(未用global聲明)的做用域爲內部做用域(對應局部命名空間);函數體內的變量稱爲局部變量閉包

>>> x = 1  ###x的做用域爲全局做用域,對應全局命名空間函數

>>> def foo():
  x = 42 ###x的做用域爲局部做用域 ,對應局部命名空間,具體的做用域只在函數體內;局部命名空間中的x指向42
  return xspa

>>> x
1
>>> foo() ###調用foo函數的時候,局部命名空間就被建立,僅做用於函數內代碼塊
42
>>> x ###調用的全局做用域(全局命名空間)中的x指向的值,因此x=1
1code

二、Shadowing屏蔽的問題;若是函數體內的局部變量和全局變量的名字相同,在函數體內引用全局變量的話,局部變量會把全局變量屏蔽掉blog

 

>>> def combine(parameter):
    external = 'berry'
    print(parameter+external)ip

>>> external = 'Sunshine'
>>> #想生成'parameter+'Sunshine''作用域

>>> combine('you are my ')
you are my berry  ###這個結果並非咱們期待的結果,由於局部變量和全局變量的名字同樣,因此局部變量把全局變量屏蔽了io

三、globals()函數,無參數,將獲取全局變量的字典類型,使用方法 globals()['全局變量名'] 返回全局變量對應的值;修改上面的函數function

 

>>> def combine(parameter):
    external = 'berry'
    print(parameter+globals()['external'])class

>>> external = 'Sunshine'
>>> combine('you are my ')
you are my Sunshine

 

四、函數內從新綁定全局變量(指向新的內容),若是函數有必要改變全局變量,使用global 變量名;用global聲明 函數體內的變量爲全局變量

 

>>> x = 1
>>> def change_global():
  global x
  x = x+1

>>> change_global()
>>> x   
2

五、嵌套做用域,一個函數內嵌套了另外一個函數,外層函數返回內層函數(內層函數未被調用只是返回);內層函數是能夠訪問外層函數的變量的,這個就叫嵌套做用域;

例子:

 

>>> 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)

相關文章
相關標籤/搜索