我想了解變量是如何由Python內部管理的。Python無法訪問變量分配導致UnboundLocalError
x = 10
def ex1():
if False:
x=1
print(x)
ex1()
當執行EX1(),它示出了UnboundLocalError因爲局部變量 'x' 的未被引用。
這是怎麼發生的? 解析是否發生在初始傳遞中,只是創建符號表並指定範圍,然後在另一個傳遞中發生解釋,並跳過x=1
,因爲它是不可訪問的?
我想了解變量是如何由Python內部管理的。Python無法訪問變量分配導致UnboundLocalError
x = 10
def ex1():
if False:
x=1
print(x)
ex1()
當執行EX1(),它示出了UnboundLocalError因爲局部變量 'x' 的未被引用。
這是怎麼發生的? 解析是否發生在初始傳遞中,只是創建符號表並指定範圍,然後在另一個傳遞中發生解釋,並跳過x=1
,因爲它是不可訪問的?
Python沒有變量聲明,所以當創建/使用變量時,它必須確定範圍本身。 Python範圍是詞法,意味着它可以訪問其封閉範圍內的變量,但不能修改它們。 寫入ex1()的方式,x = 1對於ex1()是本地的。但是,當您運行ex1()時,它會嘗試讀取x = 10,因爲它是本地的,並引發您的UnboundLocalError。 因此,該變量的管理方式,它看到一個本地聲明,運行該函數,並看到另一個本地聲明,由於範圍,不能涉及兩者。
從概念上講,這是有道理的。我不知道它是如何實施的,但我可以說明原因。
當您影響變量時,它會受到本地範圍的影響,除非您使用關鍵字global
明確告知。如果你只訪問它並且沒有任何作用,它將隱含地使用全局變量,因爲沒有定義局部變量。
x = 10
def access_global():
print x
def affect_local():
x = 0
print x
def affect_global():
global x
x = 1
print x
access_global() # 10
affect_local() # 0
print x # 10
affect_global() # 1
print x # 10
如果你這樣做的嵌套函數,類或模塊內部的規則類似:
def main():
y = 10
def access():
print y
def affect():
y = 0
print y
access() # 10
affect() # 0
print y # 10
main()
這是由父作用域從來沒有覆蓋變量可能節省痛苦的調試的時間,除非其明確說明。
編輯
拆卸巨蟒字節代碼爲我們提供了一些額外的信息來了解:
import dis
x = 10
def local():
if False:
x = 1
def global_():
global x
x = 1
print local
dis.dis(local)
print global_
dis.dis(global_)
<function local at 0x7fa01ec6cde8>
37 0 LOAD_GLOBAL 0 (False)
3 POP_JUMP_IF_FALSE 15
38 6 LOAD_CONST 1 (1)
9 STORE_FAST 0 (x)
12 JUMP_FORWARD 0 (to 15)
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
<function global_ at 0x7fa01ec6ce60>
42 0 LOAD_CONST 1 (1)
3 STORE_GLOBAL 0 (x)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
我們可以看到,對於local
功能字節代碼調用STORE_FAST
和global_
函數調用STORE_GLOBAL
。
這個問題也解釋了爲什麼它更高性能的翻譯功能,字節碼編譯避免每次函數調用時: Why python compile the source to bytecode before interpreting?
這是正確的。 –