python变量生命周期_python 变量定义及变量生命周期
第一部分
最近在寫Python的時(shí)候發(fā)現(xiàn)一個(gè)好玩的現(xiàn)象,就是在if else重定義的變量,沒有聲明全局,在外部也可以使用,
這里涉及到一個(gè)python變量生命周期的問題。
python能夠改變變量作用域的代碼段是def、class、lamda.
if/elif/else、try/except/finally、for/while 并不能涉及變量作用域的更改,
也就是說他們的代碼塊中的變量,在外部也是可以訪問的
變量搜索路徑是:本地變量->全局變量
https://img-blog.csdn.net/20161110105647895?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
http://blog.csdn.net/u012965373/article/details/53113586
第二部分
python中,對(duì)于變量作用域的規(guī)定有些不一樣。在諸如C/C++、java等編程語言中,默認(rèn)在函數(shù)的內(nèi)部是可以直接訪問在函數(shù)外定義的全局變量的,但是這一點(diǎn)在python中就會(huì)有問題,下面是一個(gè)例子。
test.py:
#!/usr/bin/python
COUNT=1
def func():
COUNT = COUNT + +1
func()
Python test.py,會(huì)運(yùn)行報(bào)錯(cuò):
Traceback (most recent call last):
File "test.py", line 8, in
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++之類的編程語言,變量名稱實(shí)際上是代表的一塊內(nèi)存區(qū)域,對(duì)該變量賦值的意思就是將新的值放入該變量指定的內(nèi)存區(qū)域。而對(duì)于python來說,所有的變量都是對(duì)內(nèi)存區(qū)域的引用,對(duì)變量賦值相當(dāng)于將變量引用的內(nèi)存從一塊區(qū)域改變到另外一塊存放新值的區(qū)域。也就是說,C/C++中,變量名和內(nèi)存區(qū)域的對(duì)應(yīng)關(guān)系不會(huì)變,變的只是對(duì)應(yīng)內(nèi)存中存放的值;而在python中,變量只是對(duì)存放其值的內(nèi)存區(qū)域的引用,變量值的改變不是因?yàn)樽兞恐赶虻膬?nèi)存區(qū)域中的值發(fā)生了變化,而是變量引用了新的存放新值的內(nèi)存區(qū)域。python中的所有變量都是相當(dāng)于java中的不可變的變量,任何一次值的改變都對(duì)應(yīng)著變量引用內(nèi)存區(qū)域的變化。區(qū)別如下圖1:
圖1 變量的比較
python中有一個(gè)id函數(shù),python中有一個(gè)id函數(shù),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)
簡(jiǎn)單地說,id函數(shù)反應(yīng)的是對(duì)象的內(nèi)存地址,看下面的實(shí)驗(yàn)結(jié)果:
test.py:
#!/usr/bin/python
COUNT = 1
for i in range(5):
COUNT = COUNT + 1
print id(COUNT)
python test.py運(yùn)行結(jié)果:
11031328
11031304
11031280
11031256
11031232
這里和上面圖上說明的相吻合,python中每一次賦值都使變量引用的內(nèi)存空間發(fā)生了改變。
回到上面“referenced before assignment”的錯(cuò)誤,之所以會(huì)發(fā)生這種錯(cuò)誤是因?yàn)閜ython在函數(shù)中發(fā)現(xiàn)對(duì)于COUNT變量的賦值,會(huì)將其添加到函數(shù)的局部命名空間(實(shí)際上,這是在函數(shù)運(yùn)行到賦值操作之前發(fā)生的)。進(jìn)行賦值操作時(shí),賦值操作符的右邊引用了COUNT變量,而這時(shí)COUNT變量只是被添加到了函數(shù)的局部命名空間,而沒有被具體賦值,所以會(huì)發(fā)生上面的錯(cuò)誤。實(shí)際上,這里問題就出在賦值操作的地方,因?yàn)橛匈x值操作導(dǎo)致該變量被添加到了函數(shù)的局部命名空間。如果沒有賦值,只是引用該變量,是沒有什么問題的,如下:
test.py:
#!/usr/bin/python
COUNT=1
def func():
temp = COUNT + 1
print "temp:",COUNT
print "COUNT:",COUNT
func()
python test.py運(yùn)行結(jié)果:
temp: 1
COUNT: 1
這樣,COUNT變量沒有被添加到函數(shù)的局部命名空間,python解釋器在函數(shù)的局部命名空間中沒有查找到它,然后,python解釋器會(huì)繼續(xù)在全局的命名空間中查找,結(jié)果在全局命名空間中找到COUNT的定義并引用它的值,所以程序運(yùn)行沒有任何問題。
到這里你可能會(huì)問,難道在函數(shù)中沒法修改全局變量的值嗎?不是的,如果要在函數(shù)中修改全局變量的值,就要在函數(shù)中對(duì)該變量進(jìn)行g(shù)lobal聲明,以告訴python解釋器,該變量是全局命名空間中的,如下:
test.py:
#!/usr/bin/python
COUNT=1
def func():
global COUNT
COUNT = COUNT + 1
print "COUNT:",COUNT
func()
python test.py運(yùn)行結(jié)果:
COUNT: 2
總結(jié)
以上是生活随笔為你收集整理的python变量生命周期_python 变量定义及变量生命周期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端js代码多文件混淆
- 下一篇: python抓取交易所_Python百行