3 回答

TA貢獻1860條經驗 獲得超9個贊
這就是閉包的工作方式。定義函數時output_after,它將text="hi there"在此函數的變量范圍內使用變量。并且只能在函數內部更改此變量。
但是,如果要使用全局變量,則需要使用global構造:
def output_after():
global text, num
print "after change: object text " ,p.var
print "after change: object number ", p.num
print "after change: basic text " ,text
print "after change: basic num ", num
眾所周知,Python中的所有變量名稱都被稱為對值的引用。因此,當我們定義函數時,我們將output_after復制所有當前上下文(對text,num,p對象的引用)。您可以使用id功能檢查對對象的引用。當您更改文本和num的值時,引用將被更改,但是對于對象p將會相同。
請檢查以下內容:
def change():
print(id(text))
text = "whats up"
print(id(text))
print(id(num))
num=5
print(id(text))
print(id(p))
p.num=10
print(id(p))
您可以看到num和text的引用已更改。

TA貢獻1898條經驗 獲得超8個贊
簡短答案:在函數外部或全局范圍內聲明的任何變量(意味著該變量不在任何類型的范圍內,例如類,方法,條件語句等)都稱為全局變量。
長調試的答案:
實際上,您的對象被聲明為全局對象。
p=test()
p.var="good bye"
p.arr = []
p.num = 5
在上面的代碼片段中,該p對象在方法范圍之外進行了聲明,從而允許所有對象都可以訪問它。方法也在test類范圍之外聲明。實際上,沒有什么阻止他們訪問它。如果要更好地理解調試,請將p對象移至其中一種方法中,例如:
def output_before():
p=test()
p.var="good bye"
p.arr = []
p.num = 5
print "before change: object text " ,p.var
print "before change: object number ", p.num
print "before change: basic text " ,text
print "before change: basic num ", num
并重新運行您的代碼,將產生:
before change: object text good bye
before change: object number 5
before change: basic text hi there
before change: basic num 1
然后出現以下錯誤:
追溯(最近一次呼叫最近):change()中的文件“ t.py”,第35行,更改中的文件“ t.py”,第29行,p.num = 10 NameError:未定義全局名稱“ p”
但是,如果要從模塊或方法內部訪問對象,則可以使用關鍵字global,并且如文檔所建議的那樣:
這是因為當您對作用域中的變量進行賦值時,該變量將成為該作用域的局部變量,并在外部作用域中隱藏任何類似命名的變量。由于foo中的最后一條語句為x分配了一個新值,因此編譯器將其識別為局部變量。因此,當較早的打印x嘗試打印未初始化的局部變量并導致錯誤時,可以通過將其聲明為全局變量來訪問外部作用域變量

TA貢獻1895條經驗 獲得超7個贊
就像Python中的其他任何變量一樣。該函數首先在本地名稱空間中檢查變量。由于未在函數內部定義對象,因此它將檢查外部命名空間,即您實際定義其的全局命名空間。
對于變量num /文本,您使用num = 5在change()。這將創建一個名為的局部變量,num并為其分配5。它不會更改全局變量。如果要全局更改它,則可以使用global關鍵字:
def change():
global text,num
num = 5 #Global num is changed
添加回答
舉報