我有一個關於Python中的全局變量的問題。 代碼如下。如果我在功能測試中不使用全局M, 會發生錯誤。 但它爲什麼不顯示字符串s的錯誤。我不把它聲明爲全球性的。python字符串是默認全局的
global M
M = []
s = "abc"
def test():
### global M
print M
M.append(s)
打印中號 UnboundLocalError:分配
我有一個關於Python中的全局變量的問題。 代碼如下。如果我在功能測試中不使用全局M, 會發生錯誤。 但它爲什麼不顯示字符串s的錯誤。我不把它聲明爲全球性的。python字符串是默認全局的
global M
M = []
s = "abc"
def test():
### global M
print M
M.append(s)
打印中號 UnboundLocalError:分配
之前引用局部變量「M」,我不太清楚你會得到什麼樣的錯誤,但你似乎可以用全球的錯。
聲明全局變量不需要(或建議)全局關鍵字。它被用在函數內部來指定不應該創建局部變量。考慮2個不同的功能:
M = []
def test1():
M = [1]
def test2():
global M
M = [2]
test1的將創建一個新的局部變量,而TEST2將寫入全球併購
If I do not use global M in function test, It would issue error.
你的這種說法是根本不真正!
>>> M = []
>>> s = "abc"
>>>
>>> def test():
... M.append(s)
...
>>> M
[]
>>> test()
>>> M
['abc']
我想你混淆了兩個完全和完全不同的概念:
結合barename - 通過一些其他的通常是由分配(即=
),還可能 語句(def
,& C)
調用一個方法(S UCH作爲append
),該「可」發生變異對象 (僅當該對象是可變的,並且該方法當然是一個增變,但 不會應用於當對象是一個列表,並且該方法是append
)
我不確定人們爲什麼會混淆兩極分離的概念,但他們肯定可以。也許這是事實,一些非純粹的香草「種」的任務實際上是「幕後」調用一種(特殊)方法,例如,分配給合格的名字(a.b=c
實際上是調用type(a).__setitem__(a, b)
,所以,調用方法,而不是重新綁定任何裸號)和增加的賦值(a+=b
實際上是做a = type(a).__iadd__(a, b)
,所以,都調用方法和重新綁定一個裸號)。
你需要global
(唉),當且僅當你正在做的「1」:重新綁定一個barename(包括增量賦值但不包括任何其它特殊情況下重新綁定的話)。除非它真的不可或缺(並且很多人會說它從來不是真的不可或缺......只是「在某些情況下顯然有點方便」);-)。
當我把「在「M.append(s)」之前打印M「。 – chnet 2010-10-01 15:17:31
@chnet請將錯誤信息複製到您的問題中,而不是隻是在談論它。你迫使人們閱讀你的思想,這不起作用。 – 2010-10-01 15:21:36
@chnet,在我的答案中給出的代碼片段中的函數test中添加一個'print M'語句就好了,所以,_again_,你的語句只是錯誤的。你的代碼必須與上述內容有重大區別,並且我們不可能猜測可能存在哪些差異,因爲你將代碼隱藏起來並做出錯誤陳述,而不是**向我們展示代碼**! - ) – 2010-10-01 15:30:46
由於@Alex馬爾泰利指出你的代碼所示不會產生錯誤,但將是,除了現在的基礎上@ cobbal的回答(對不起,我不能評論還)你需要非常小心當說到這裏
範圍在@ cobbal的回答是:
def test1():
M = [1]
創建一個新的變量M
函數的局部test1
。但是,如果不是在執行任務M = [1]
,而是使用M.append(1)
(如問題中所做的那樣),而不是創建新的局部變量,Python會從函數的本地範圍查找更高範圍,在這種情況下,全局範圍確實已經有一個指向空列表的變量M
。在這種情況下,Python會找到這個變量並簡單地附加到現有列表中,導致全局M
現在指向[1]
。
在第二個例子:
def test2():
global M
M = [2]
使用該global
關鍵字是必要的,以避免否則會發生的本地分配。通過調用global
使用M
在本地範圍內的函數將指向已有的[]
對象的函數外部。
您可以通過在函數的各種形式中插入id(M)
來證明這一點,以顯示哪些實現會導致函數內部的M
指向全局對象或本地對象。
請包括您得到的錯誤消息的文本。 – 2010-10-01 14:59:26
感謝您幫助格式化代碼。 – chnet 2010-10-01 14:59:47
如果您發佈更多關於您嘗試解決的問題,我們可能會找到一個很好的方法來分解它,以便您不需要使用全局變量。相信我,你不想這樣做。也許發佈另一個問題,因爲「我怎樣才能重構此代碼來擺脫全局...」 – Daenyth 2010-10-01 15:18:33