日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python local variable_python学习笔记 - local, global and free variable

發(fā)布時間:2024/9/19 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python local variable_python学习笔记 - local, global and free variable 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

理解 global and local variable

現(xiàn)在我想在子代碼塊中對global variable重新賦值,實現(xiàn)代碼如下:

code snippet 1

>>>

>>> var = 'outer val'

>>> def func1():

... var = 'inner val'

... print "Inside func1(), val: ", var

... print "locals(): ", locals()

... print "globals(): ", globals()

...

>>> func1()

Inside func1(), val: inner val

locals(): {'var': 'inner val'}

globals(): {'func1': , '__builtins__': , '__package__': None, 'var': 'outer val', '__name__': '__main__', '__doc__': None}

>>>

>>> print "var: ", var

var: outer val

>>>

但結(jié)果并非如我所愿。在func1內(nèi)部,var的值為"inner val",離開了函數(shù),其值又變成了"outer val",為什么?看看輸出的本地和全局變量列表答案就明顯了,var既出現(xiàn)在本地變量列表,又出現(xiàn)在全局變量列表,但綁定的值不一樣,因為他們本就是兩個不同的變量。也就是說,當(dāng)你想在子代碼塊中對某個全局變量重新賦值時,實際上你只是定義了一個同名的本地變量,這并不會改變?nèi)肿兞康闹怠?/p>

如何修改全局變量的值?需要在函數(shù)中使用global statement。先看一例:

code snippet 2

>>> def func2():

... global var2

... var2 = 'who am i'

... print "locals(): ", locals()

... print "globals(): ", globals()

...

>>> func2()

locals(): {}

globals(): {'func2': , 'func1': , 'var2': 'who am i', '__builtins__': , '__package__': None, '__name__': '__main__', '__doc__': None}

>>>

>>> print var2

who am i

>>>

看看輸出結(jié)果,發(fā)現(xiàn)竟然可以在函數(shù)代碼塊中定義一個全局變量,太神奇了!因為全局變量的作用域是整個模塊,所以離開了定義函數(shù),依然可以讀取它。

有了這個做鋪墊,再來嘗試修改全局變量的值:

code snippet 3

>>> global_var = 'outer'

>>> def func3():

... global global_var

... global_var = 'inner'

... print "locals(): ", locals()

... print "globals(): ", globals()

...

>>> func3()

locals(): {}

globals(): {'func3': , '__builtins__': , 'global_var': 'inner', '__package__': None, '__name__': '__main__', '__doc__': None}

>>>

>>> print global_var

inner

>>>

妥妥的了。做個總結(jié)吧,要在函數(shù)代碼塊中修改全局變量的值,就使用global statement聲明一個同名的全局變量,然后就可以修改其值了;如果事先不存在同名全局變量,此語句就會定義一個,即使離開了當(dāng)前函數(shù)也可以使用它。

理解 global and free variable

來自于python官方文檔 Execution Model 的解釋:

When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block’s environment.

If a name is bound in a block, it is a local variable of that block. If a name is bound at the module level, it is a global variable. (The variables of the module code block are local and global.) If a variable is used in a code block but not defined there, it is a free variable.

這段文檔確實應(yīng)該多讀多想。全局變量不用多說,一看就懂。不過這句話有點(diǎn)讓人費(fèi)解,“The variables of the module code block are local and global”,我是這樣理解的,對于模塊代碼塊來說,模塊級的變量就是它的本地變量,但對于模塊中其他更小的代碼塊來說,這些變量就是全局的。那再進(jìn)一步,什么是模塊級的變量,是指那些在模塊內(nèi)部,但在其所有子代碼塊之外定義的變量嗎?用代碼驗證哈:

code snippet 4

>>>

>>> global_var = 'global_val'

>>> def showval():

... local_var = 'local_val'

... print "before defining inner func, showval.locals(): ", locals()

... def innerFunc():

... print "Inside innerFunc, local_var: ", local_var

... print "innerFunc.locals:", locals()

... print "after defining inner func, showval.locals(): ", locals()

... print "showval.globals():", globals()

... return innerFunc

...

>>> a_func = showval()

before defining inner func, showval.locals(): {'local_var': 'local_val'}

after defining inner func, showval.locals(): {'innerFunc': , 'local_var': 'local_val'}

showval.globals(): {'__builtins__': , 'global_var': 'global_val', '__package__': None, '__name__': '__main__', '__doc__': None, 'showval': }

>>>

>>> a_func

>>> a_func()

Inside innerFunc, local_var: local_val

innerFunc.locals: {'local_var': 'local_val'}

>>>

基于自己的理解來分析哈輸出結(jié)果:變量local_var、函數(shù)innerFunc是在函數(shù)代碼塊showval中定義的,所以它們是該代碼塊的局部變量。首次輸出globals時,變量global_var、函數(shù)showval在所有子代碼塊之外定義,所以它們是當(dāng)前模塊的全局變量。再次輸出globals時,多了一個全局變量globals。

注意看,全局變量中還有:__builtins__、__package__、__name__、__doc__。這些變量的含義可參考 python模塊的內(nèi)置方法。

現(xiàn)在來看自由變量,local_var被innerFunc函數(shù)使用,但是并未在其中定義,所以對于innerFunc代碼塊來說,它就是自由變量。問題來了,自由變量為什么出現(xiàn)在

innerFunc.locals()的輸出結(jié)果中?這就需要看看locals()API文檔了:

Update and return a dictionary representing the current local symbol table. Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

好像我已經(jīng)把自由變量搞得很清楚了,但是真的嗎?看看下面的代碼:

code snippet 5

>>>

>>> global_var = 'foo'

>>> def ex1():

... local_var = 'bar'

... print "locals(): ", locals()

... print global_var

... print local_var

... global_var = 'foo2'

...

>>> ex1()

locals(): {'local_var': 'bar'}

Traceback (most recent call last):

File "", line 1, in

File "", line 4, in ex1

UnboundLocalError: local variable 'global_var' referenced before assignment

>>>

>>> def ex2():

... local_var = 'bar'

... print "locals(): ", locals()

... print "globals(): ", globals()

... print global_var

... print local_var

...

>>> ex2()

locals(): {'local_var': 'bar'}

globals(): {'__builtins__': , 'global_var': 'foo', '__package__': None, 'ex2': , 'ex1': , '__name__': '__main__', '__doc__': None}

foo

bar

>>>

首先分析哈輸出結(jié)果。執(zhí)行ex1()函數(shù)失敗,原因:UnboundLocalError: local variable 'global_var' referenced before assignment,意思是global_var這個本地變量還未賦值就被引用了。等等,global_var怎么是本地變量了?與ex2()函數(shù)做個對比,發(fā)現(xiàn)因為有這行代碼global_var = 'foo2',解釋器就認(rèn)為global_var是一個本地變量,而不是全局變量。

那最外面定義的global_var到底是本地還是全局變量?看看第二部分的輸出,可以很確定地知道最外面定義的global_var是一個全局變量。

簡單點(diǎn)說,就是這里存在兩個同名的變量,一個是最外面定義的全局變量global_var,另一個是函數(shù)ex1()中定義的本地變量global_var。

再等等,矛盾出現(xiàn)了。按照之前對自由變量的理解,在一個代碼塊中被使用,但是并未在那兒定義,外部定義的global_var在函數(shù)塊ex1()中被使用,完全符合,它為什么不是一個自由變量?還是我們對自由變量的理解有問題?

與code snippet 4中確定是自由變量的local_var比較,發(fā)現(xiàn)local_var是一個函數(shù)代碼塊的本地變量,而code snippet 5中的global_var是一個模塊代碼塊的本地變量。當(dāng)local_var被定義它的函數(shù)內(nèi)的嵌套函數(shù)使用時,它就變成了一個自由變量,此時函數(shù)的嵌套就形成了閉包(closure),可見自由變量的應(yīng)用場景就是閉包。

而global_var對模塊本身來說它是一個本地變量,但在模塊中的其他代碼塊中也可以使用它,所以它同時又是一個全局變量。

到這兒就可以對自由變量的理解做個總結(jié)了:如果一個變量在函數(shù)代碼塊中定義,但在其他代碼塊中被使用,例如嵌套在外部函數(shù)中的閉包函數(shù),那么它就是自由變量。注意,給變量賦值不算是使用該變量,使用指的是讀取變量值,具體區(qū)別后面再詳述。

理解 free and local variable

修改全局變量的值需要使用global,那修改自由變量的值又會如何?先用自然思維方式試試:

code snippet 6

>>>

>>> def outerfunc():

... var = 'free'

... def innerfunc():

... var = 'inner'

... print "Inside innerfunc, var: ", var

... print "Inside innerfunc, locals(): ", locals()

... innerfunc()

... print "var: ", var

... print "locals(): ", locals()

...

>>> outerfunc()

Inside innerfunc, var: inner

Inside innerfunc, locals(): {'var': 'inner'}

var: free

locals(): {'var': 'free', 'innerfunc': }

>>>

在innerfunc函數(shù)中我試圖修改自由變量var的值,結(jié)果卻發(fā)現(xiàn)修改只在innerfunc函數(shù)內(nèi)有效,離開此函數(shù)后其值仍然是"free"??纯摧敵龅膐uterfunc和innerfunc函數(shù)的本地變量列表就知道咋回事兒了。當(dāng)你想在閉包函數(shù)中對自由變量重新賦值時,實際上你只是在這里定義了一個本地變量,這并不會改變自由變量的值。

code snippet 7

class Namespace: pass

def ex7():

ns = Namespace()

ns.var = 'foo'

def inner():

ns.var = 'bar'

print 'inside inner, ns.var is ', ns.var

inner()

print 'inside outer function, ns.var is ', ns.var

ex7()

# console output

inside inner, ns.var is bar

inside outer function, ns.var is bar

code snippet 8

def ex8():

ex8.var = 'foo'

def inner():

ex8.var = 'bar'

print 'inside inner, ex8.var is ', ex8.var

inner()

print 'inside outer function, ex8.var is ', ex8.var

ex8()

# console output

inside inner, ex8.var is bar

inside outer function, ex8.var is bar

參考資源:

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的python local variable_python学习笔记 - local, global and free variable的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。