国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python新手在作用域方面經(jīng)常容易碰到的問題

2020-02-23 00:30:52
字體:
供稿:網(wǎng)友

通常,當(dāng)我們定義了一個(gè)全局變量(好吧,我這樣說是因?yàn)橹v解的需要——全局變量是不好的),我們用一個(gè)函數(shù)訪問它們是能被Python理解的:
 

bar = 42def foo():  print bar

在這里,我們在foo函數(shù)里使用了全局變量bar,然后它也如預(yù)想的能夠正常運(yùn)行:
 

>>> foo()42

這樣做很酷。通常,我們在使用了這個(gè)特性之后就想在所有的代碼里用上它。如果像以下的例子中使用的話還是能夠正常運(yùn)行的:
 

bar = [42]def foo():  bar.append(0)foo() >>> print bar[42, 0]

但是,如果我們把bar變一下呢:
 

>>> bar = 42... def foo():...   bar = 0... foo()... print bar42

我們可以看到foo函數(shù)運(yùn)行的好好的并且沒有拋出異常,但是當(dāng)我們打印bar的值的時(shí)候會發(fā)現(xiàn)它的值仍然是42。造成這種情況的原因就是 bar=0 這行代碼,它沒有改變?nèi)肿兞縝ar的值,而是創(chuàng)建了一個(gè)名字也叫bar的局部變量并且它的值為0。這是個(gè)很難發(fā)現(xiàn)的bug,這會讓沒有真正理解Python作用域的新手非常痛苦。為了理解Python是如何處理局部變量和全局變量的,我們來看一種更少見的,但是可能會更讓人困惑的錯(cuò)誤,我們在打印bar的值后定義一個(gè)叫bar這個(gè)局部變量:
 

bar = 42def foo():  print bar  bar = 0

這樣寫應(yīng)該是不會出錯(cuò)的,不是嗎?我們在打印了值之后定義了相同名稱的變量,所以這應(yīng)該是不會影響的(Python畢竟是一種解釋型語言),真的是這樣嗎?

 

出錯(cuò)了

這怎么可能呢?好吧,這里有兩處錯(cuò)誤。第一點(diǎn)就是關(guān)于Python的,作為一種解釋型語言(非常酷,我們都同意這一點(diǎn)),是一行一行地執(zhí)行的。而事實(shí)上,Python是一個(gè)聲明一個(gè)聲明執(zhí)行的。為了讓你對我想表達(dá)的意思有點(diǎn)感覺,趕緊打開你最愛的shell,然后輸入以下代碼:
 

def foo():

按回車鍵。正如你看到的,shell里面并沒有打出任何輸出而是等著讓你繼續(xù)函數(shù)的定義。Shell里會一直這樣直到你停止定義函數(shù)。這是因?yàn)槎x函數(shù)是一個(gè)聲明。好吧,這是一個(gè)混合的聲明,里面包含了一些其他的聲明,但它仍然是一個(gè)聲明。直到函數(shù)被調(diào)用,不然這個(gè)函數(shù)里的內(nèi)容是不會執(zhí)行的。真正執(zhí)行的是一個(gè)function類型的對象被創(chuàng)建出來了。

這引導(dǎo)我們來關(guān)注第二點(diǎn)。再強(qiáng)調(diào)一下,Python的動(dòng)態(tài)性和解釋型的特性讓我們相信當(dāng) print bar 這行被執(zhí)行的時(shí)候,Python會在首先在局部作用域里尋找叫bar的變量然后再去尋找全局作用域里的。但實(shí)際上發(fā)生的是局部作用域不是完全動(dòng)態(tài)的。當(dāng)def 這個(gè)聲明執(zhí)行的時(shí)候,Python會靜態(tài)地從這個(gè)函數(shù)的局部作用域里獲取信息。當(dāng)來到 bar=0 這行的時(shí)候(不是執(zhí)行到這行代碼,而是當(dāng)Python解釋器讀到這行代碼的時(shí)候),它會把'bar'這個(gè)變量加入到foo函數(shù)的局部變量列表里。當(dāng)foo函數(shù)執(zhí)行并且Python準(zhǔn)備執(zhí)行print bar這行的時(shí)候,它就會在局部的作用域里尋找這個(gè)變量,由于這個(gè)過程是靜態(tài)的,Python知道這個(gè)變量還沒有被賦值,這個(gè)變量沒有值,所以拋出了異常。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鹤山市| 伊宁县| 太白县| 长春市| 宜兰县| 洛川县| 玉林市| 青州市| 收藏| 铜山县| 通城县| 麻栗坡县| 环江| 铜鼓县| 牡丹江市| 宣城市| 交城县| 阜宁县| 辽宁省| 兴城市| 杨浦区| 东源县| 怀来县| 南昌县| 丹寨县| 宝鸡市| 海兴县| 宁明县| 庄浪县| 本溪| 敦煌市| 沐川县| 徐闻县| 鄂伦春自治旗| 彰化市| 三门峡市| 辛集市| 苍南县| 张家港市| 兰溪市| 松原市|