python中,對於變量作用域的規定有些不一樣。
在諸如C/C++、java等編程語言中,默認在函數的內部是能夠直接訪問在函數外定義的全局變量的,可是這一點在python中就會有問題。以下是一個樣例。
test.py: #!/usr/bin/python COUNT=1 def func(): COUNT = COUNT + 1 func() Python test.py。會執行報錯: Traceback (most recent call last): File "test.py", line 8, in <module> func() File "test.py", line 6, in func COUNT = COUNT + 1 UnboundLocalError: local variable 'COUNT' referenced before assignment
“UnboundLocalError: local variable 'COUNT' referenced before assignment”的意思是變量COUNT在賦值之前被引用。
這里要知道python和其他編程語言不一樣的地方。像C/C++之類的編程語言。變量名稱實際上是代表的一塊內存區域。對該變量賦值的意思就是將新的值放入該變量指定的內存區域。而對於python來說。全部的變量都是對內存區域的引用,對變量賦值相當於將變量引用的內存從一塊區域改變到另外一塊存放新值的區域。
也就是說,C/C++中,變量名和內存區域的相應關系不會變,變的僅僅是相應內存中存放的值;而在python中,變量僅僅是對存放其值的內存區域的引用,變量值的改變不是由於變量指向的內存區域中的值發生了變化,而是變量引用了新的存放新值的內存區域。
python中的全部變量都是相當於java中的不可變的變量,不論什么一次值的改變都相應着變量引用內存區域的變化。
差別例如以下圖1:
圖1 變量的比較
python中有一個id函數,python中有一個id函數。help(id)能夠看到它的說明。例如以下:
Help on built-in function id in module __builtin__: id(...) id(object) -> integer Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects.(Hint: it's the object's memory address.) (END)
簡單地說,id函數反應的是對象的內存地址,看以下的實驗結果:
test.py: #!/usr/bin/python COUNT = 1 for i in range(5): COUNT = COUNT + 1 print id(COUNT) python test.py執行結果: 11031328 11031304 11031280 11031256 11031232
這里和上面圖上說明的相吻合,python中每一次賦值都使變量引用的內存空間發生了改變。
回到上面“referenced before assignment”的錯誤,之所以會發生這樣的錯誤是由於python在函數中發現對於COUNT變量的賦值。會將其加入到函數的局部命名空間(實際上,這是在函數執行到賦值操作之前發生的)。
進行賦值操作時。賦值操作符的右邊引用了COUNT變量。而這時COUNT變量僅僅是被加入到了函數的局部命名空間,而沒有被詳細賦值,所以會發生上面的錯誤。實際上。這里問題就出在賦值操作的地方,由於有賦值操作導致該變量被加入到了函數的局部命名空間。假設沒有賦值,僅僅是引用該變量,是沒有什么問題的,例如以下:
test.py: #!/usr/bin/python COUNT=1 def func(): temp = COUNT + 1 print "temp:",COUNT print "COUNT:",COUNT func() python test.py執行結果: temp: 1 COUNT: 1
這樣,COUNT變量沒有被加入到函數的局部命名空間,python解釋器在函數的局部命名空間中沒有查找到它。然后。python解釋器會繼續在全局的命名空間中查找,結果在全局命名空間中找到COUNT的定義並引用它的值,所以程序執行沒有不論什么問題。
到這里你可能會問,難道在函數中沒法改動全局變量的值嗎?不是的,假設要在函數中改動全局變量的值,就要在函數中對該變量進行global聲明,以告訴python解釋器,該變量是全局命名空間中的,例如以下:
test.py: #!/usr/bin/python COUNT=1 def func(): global COUNT COUNT = COUNT + 1 print "COUNT:",COUNT func() python test.py執行結果: COUNT: 2
OK. ^_^