Python全局變量和局部變量

python中,對於變量做用域的規定有些不同。java

在諸如C/C++、java等編程語言中,默認在函數的內部是可以直接訪問在函數外定義的全局變量的,但是這一點在python中就會有問題。如下是一個樣例。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中的不可變的變量,不論什麼一次值的改變都相應着變量引用內存區域的變化。ide

差異例如如下圖1:函數


圖1 變量的比較post

python中有一個id函數,python中有一個id函數。help(id)可以看到它的說明。例如如下:
ui

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變量的賦值。會將其加入到函數的局部命名空間(實際上,這是在函數執行到賦值操做以前發生的)。code

進行賦值操做時。賦值操做符的右邊引用了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. ^_^
相關文章
相關標籤/搜索