最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2015年04月03日 10:32:20   作者:Amir Rachum  
這篇文章主要介紹了Python新手在作用域方面經(jīng)常容易碰到的問(wèn)題,全局變量和局部變量方面的知識(shí)在Python學(xué)習(xí)當(dāng)中是基礎(chǔ)中的基礎(chǔ),需要的朋友可以參考下

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

bar = 42
def foo():
  print bar

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

>>> foo()
42

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

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

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

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

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

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

這樣寫應(yīng)該是不會(huì)出錯(cuò)的,不是嗎?我們?cè)诖蛴×酥抵蠖x了相同名稱的變量,所以這應(yīng)該是不會(huì)影響的(Python畢竟是一種解釋型語(yǔ)言),真的是這樣嗎?

 

出錯(cuò)了

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

def foo():

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

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

你可能會(huì)問(wèn):為什么不能在聲明函數(shù)的時(shí)候拋出這個(gè)異常呢?Python可以知道預(yù)先知道bar這個(gè)變量在賦值前被引用了。這個(gè)問(wèn)題的答案就是Python無(wú)法知道這個(gè)局部變量bar是否被賦值了。看看下面的例子:
 

bar = 42
def foo(baz):
  if baz > 0:
    print bar
  bar = 0

Python在動(dòng)態(tài)和靜態(tài)之間玩了一個(gè)微妙的游戲。它唯一知道的事情就是bar是被賦值了,但它不知道在賦值前被引用這個(gè)異常是否存在直到它真的發(fā)生。好吧,老實(shí)說(shuō),它根本就不知道這個(gè)變量是否被賦值!
 

bar = 42
def foo():
  print bar
  if False:
    bar = 0
 
>>> foo()
Traceback (most recent call last):
 File "<pyshell#17>", line 1, in <module>
  foo()
 File "<pyshell#16>", line 3, in foo
  print bar
UnboundLocalError: local variable 'bar' referenced before assignment

看到上面的代碼里面,雖然我們作為一種智能生物能夠很清楚的知道不會(huì)給bar賦值。Python無(wú)視了那個(gè)事實(shí)而是仍然聲明了bar這個(gè)局部變量。

關(guān)于這個(gè)問(wèn)題我已經(jīng)說(shuō)了夠長(zhǎng)了。我們需要的是解決方案,我會(huì)在這里給出兩個(gè)解決方法。
 

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

第一就是使用global關(guān)鍵字。這是不言自明的。這會(huì)讓Python知道bar是一個(gè)全局變量而不是局部變量。

第二個(gè)方法,也是更推薦使用的,就是不要使用全局變量。在我的大量Python開發(fā)工作中從來(lái)沒(méi)有用到global這個(gè)關(guān)鍵字。能知道怎么用它就行了,但最終還是要盡量避免使用它。如果你想保存在代碼里至始至終用到的值的時(shí)候,把它定義為一個(gè)類的屬性。用這種方法的話就完全不需要用global了,當(dāng)你要用這個(gè)值的時(shí)候,通過(guò)類的屬性來(lái)訪問(wèn)就可以了:
 

>>> class Baz(object):
...   bar = 42
...
... def foo():
...   print Baz.bar # global
...   bar = 0 # local
...   Baz.bar = 8 # global
...   print bar
...
... foo()
... print Baz.bar
42
0
8

相關(guān)文章

  • 你知道怎么用Python監(jiān)控聊天記錄嗎

    你知道怎么用Python監(jiān)控聊天記錄嗎

    今天有位同事和我吐槽關(guān)于公司 XX 的問(wèn)題,我告訴他不要在公司電腦上說(shuō)這些,因?yàn)楹芸赡軙?huì)被狙擊,這位同事剛開始還不信,直到我寫了這邊文章,他才恍然大悟
    2021-10-10
  • python實(shí)現(xiàn)兩個(gè)文件合并功能

    python實(shí)現(xiàn)兩個(gè)文件合并功能

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)兩個(gè)文件合并功能,一個(gè)簡(jiǎn)單的文件合并程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • python中threading.Semaphore和threading.Lock的具體使用

    python中threading.Semaphore和threading.Lock的具體使用

    python中的多線程是一個(gè)非常重要的知識(shí)點(diǎn),本文主要介紹了python中threading.Semaphore和threading.Lock的具體使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2023-08-08
  • 在Pytorch中計(jì)算卷積方法的區(qū)別詳解(conv2d的區(qū)別)

    在Pytorch中計(jì)算卷積方法的區(qū)別詳解(conv2d的區(qū)別)

    今天小編就為大家分享一篇在Pytorch中計(jì)算卷積方法的區(qū)別詳解(conv2d的區(qū)別),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python的dict字典結(jié)構(gòu)操作方法學(xué)習(xí)筆記

    Python的dict字典結(jié)構(gòu)操作方法學(xué)習(xí)筆記

    這篇文章主要介紹了Python的dict字典結(jié)構(gòu)操作方法學(xué)習(xí)筆記本,字典的操作是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-05-05
  • 使用Python輕松完成垃圾分類(基于圖像識(shí)別)

    使用Python輕松完成垃圾分類(基于圖像識(shí)別)

    這篇文章主要介紹了使用Python輕松完成垃圾分類(基于圖像識(shí)別),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • torch.utils.data.DataLoader與迭代器轉(zhuǎn)換操作

    torch.utils.data.DataLoader與迭代器轉(zhuǎn)換操作

    這篇文章主要介紹了torch.utils.data.DataLoader與迭代器轉(zhuǎn)換操作,文章內(nèi)容接受非常詳細(xì),對(duì)正在學(xué)習(xí)或工作的你有一定的幫助,需要的朋友可以參考一下
    2022-02-02
  • 詳解如何用Python實(shí)現(xiàn)感知器算法

    詳解如何用Python實(shí)現(xiàn)感知器算法

    今天給大家?guī)?lái)的是關(guān)于Python的相關(guān)知識(shí),文章圍繞著如何用Python實(shí)現(xiàn)感知器算法展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 如何運(yùn)用sklearn做邏輯回歸預(yù)測(cè)

    如何運(yùn)用sklearn做邏輯回歸預(yù)測(cè)

    這篇文章主要介紹了如何運(yùn)用sklearn做邏輯回歸預(yù)測(cè)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • python隨機(jī)獲取列表中某一元素的方法

    python隨機(jī)獲取列表中某一元素的方法

    本文主要介紹了python隨機(jī)獲取列表中某一元素的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02

最新評(píng)論

波密县| 梧州市| 安宁市| 安丘市| 和静县| 高清| 邢台市| 桦甸市| 顺昌县| 临清市| 衡山县| 金山区| 迁安市| 嘉峪关市| 印江| 广平县| 澎湖县| 宣汉县| 临澧县| 扎赉特旗| 南宫市| 南丹县| 高阳县| 勐海县| 岱山县| 印江| 治县。| 汤原县| 乌鲁木齐县| 安达市| 万盛区| 大庆市| 邵东县| 玛曲县| 武川县| 吉安市| 陆良县| 林西县| 溧阳市| 绵阳市| 康定县|