日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

給妹子講python-S01E18初探函數(shù)作用域

 tology 2018-09-11

【要點(diǎn)搶先看】

1.變量的四種作用域
2.函數(shù)變量的LEGB作用域搜索機(jī)制
3.利用global關(guān)鍵字進(jìn)行全局變量修改

上一小節(jié)我們引入了函數(shù)的概念,這一節(jié)我們開(kāi)始接觸函數(shù)里的一個(gè)非常重要的話(huà)題:變量的作用域。

當(dāng)你在一個(gè)程序中使用變量名時(shí),python創(chuàng)建、改變或查找變量名都是在所謂的命名空間中進(jìn)行的,也就是我們要說(shuō)的變量的作用域。在代碼中給一個(gè)變量賦值的地方?jīng)Q定了這個(gè)變量將存在于哪一個(gè)命名空間,也就是他的可見(jiàn)范圍。

def之中的變量名和def之外的變量名并不沖突,一個(gè)在def之外被賦值(例如,在另外一個(gè)def之中或者在模塊文件的頂層)的變量X與在這個(gè)def之中賦值的變量X是完全不同的變量。

所以我們看出,變量的作用域完全是由變量在程序文件中源代碼的位置而決定,而不是由函數(shù)調(diào)用決定。

【妹子說(shuō)】好啦,說(shuō)了這么多概念,還是用例子說(shuō)話(huà)吧!

x = 99
def func():
    x = 88
    print(x)

func()
print(x)

88
99

這里就可以看出,在這個(gè)模塊文件中:語(yǔ)句X=99,我們創(chuàng)建了一個(gè)名為X的全局變量(在這個(gè)函數(shù)所在的模塊文件中可見(jiàn)),但是X=88這個(gè)賦值語(yǔ)句創(chuàng)建了一個(gè)本地變量X(只在def語(yǔ)句內(nèi)是可見(jiàn)的)。

盡管這兩個(gè)變量都是X,但是他們作用域可以把它們區(qū)別開(kāi)來(lái)。實(shí)際上,函數(shù)的作用域有助于防止程序之中變量名的沖突,并且有助于函數(shù)成為更加獨(dú)立的程序單元。

【妹子說(shuō)】哦,我大概對(duì)作用域有那么點(diǎn)概念了。

那下面我們接著展開(kāi)具體介紹函數(shù)的四個(gè)作用域:LEGB,即L本地作用域,E內(nèi)嵌作用域,G全局作用域和B內(nèi)置作用域。

在一個(gè)函數(shù)中定義的是本地作用域,而模塊(也就是一個(gè)xxx.py文件)中定義的是全局作用域。而內(nèi)置作用域,我們使用時(shí)是直接使用變量名而不需要導(dǎo)入任何模塊,比如一些內(nèi)置的函數(shù)名:print等等

這里再?gòu)?qiáng)調(diào)一下python中所謂的全局作用域:

全局作用域的作用范圍僅限于單個(gè)文件,別被全局二字所迷惑,這里的全局指的是一個(gè)文件的頂層的變量名僅對(duì)于這個(gè)文件內(nèi)部的代碼而言是全局的,在python中聽(tīng)到全局,你就應(yīng)該想到模塊二字。

變量名由模塊文件隔開(kāi),并且必須精確的導(dǎo)入一個(gè)模塊文件才能夠使用這個(gè)文件中使用的變量名。

再說(shuō)說(shuō)本地作用域:每次對(duì)函數(shù)的調(diào)用都創(chuàng)建一個(gè)新的本地作用域,賦值的變量名除非聲明為全局變量或非本地變量,否則均為本地變量。在默認(rèn)的情況下,所有函數(shù)定義的內(nèi)部變量名都位于本地作用域(與函數(shù)調(diào)用相關(guān)的)內(nèi)。

再來(lái)看一個(gè)例子來(lái)演示一下這兩種作用域:

x = 99
def func(y):
    z = x + y
    return z

print(func(1))

100

這個(gè)例子中出現(xiàn)了全局作用域內(nèi)變量名:x和func

因?yàn)閤是在模塊文件頂層注冊(cè)的,所以他是全局變量;他能夠在函數(shù)內(nèi)部進(jìn)行引用,僅僅是引用變量不需要進(jìn)行全局變量聲明。

也有本地作用域變量名,y,z

z和參數(shù)y都是本地變量,只在函數(shù)運(yùn)行時(shí)存在,因?yàn)樗麄兌际窃诤瘮?shù)定義內(nèi)部進(jìn)行賦值的,前面我們說(shuō)過(guò)函數(shù)的參數(shù)也是通過(guò)賦值進(jìn)行傳遞的。

這種變量名隔離機(jī)制存在的意義在于本地變量是作為臨時(shí)的變量名,只有在函數(shù)運(yùn)行的時(shí)候才需要它們,例如,y和z都只存在于函數(shù)內(nèi)部,這些變量名不會(huì)與模塊命名空間內(nèi)的變量名(同理,與其他函數(shù)內(nèi)的變量名)產(chǎn)生沖突。

【妹子說(shuō)】那么如果一段程序中,不同作用域內(nèi)的幾個(gè)變量名稱(chēng)相同怎么辦?

好問(wèn)題!這正是python的LEGB變量名搜索機(jī)制要解決的問(wèn)題。

當(dāng)在python中使用某個(gè)變量名時(shí),python按照L-E-G-B的順序依次搜索四個(gè)作用域,L本地作用域,E即上一層def或者lambda的本地作用域,之后是全局作用域G,最后是內(nèi)置作用域B,并且在第一處能找到作用名的地方停下來(lái),如果變量名在這一次搜索中沒(méi)有找到,python會(huì)報(bào)錯(cuò)。

因此按照LEGB法則中規(guī)定的變量搜索順序,在本地作用域中的變量名是會(huì)在本地作用域中覆蓋在全局作用域和內(nèi)置作用域中有相同變量名的變量,全局變量名會(huì)覆蓋內(nèi)置的同名變量名。

【妹子說(shuō)】話(huà)不多說(shuō),上例子

x = 88
def func():
    x = 99
    print(x)

func()
print(x)

99
88

在這一段程序中,本地變量名x覆蓋了全局變量名x,此時(shí)本地和全局的兩個(gè)變量雖然都叫x,但他們是完全不同的變量。

def func():
    open = 1
    open('test.txt')

func()

Traceback (most recent call last):
 File 'E:/12homework/12homework.py', line 5in <module>
   func()
 File 'E:/12homework/12homework.py', line 3in func
   open('test.txt')
TypeError: 'int' object is not callable

這個(gè)例子中,本地作用域中的變量名open就覆蓋了內(nèi)置作用域中的變量名open,因此再使用open去打開(kāi)文件,此時(shí)的操作就無(wú)法使用,因?yàn)槲募蜷_(kāi)的open函數(shù)變量被open=1這個(gè)本地?cái)?shù)值變量覆蓋了。

強(qiáng)調(diào)一點(diǎn):這里我們提到的只是在本地作用域去引用或者覆蓋全局變量和內(nèi)置變量。

但是,請(qǐng)注意!如果試圖去修改,即在函數(shù)內(nèi)部試圖改變函數(shù)外部聲明的值,那就得用global和nonlocal關(guān)鍵字了。

global關(guān)鍵字

之前我們說(shuō)過(guò)python中的變量不用聲明,直接賦值使用,但是這個(gè)global關(guān)鍵字看上去就像一個(gè)聲明,但是他不是一個(gè)類(lèi)型的聲明,而是一個(gè)變量命名空間的聲明,它告訴python函數(shù)打算生成一個(gè)或多個(gè)全局變量。應(yīng)用他,就可以在函數(shù)內(nèi)部對(duì)全局變量進(jìn)行引用和修改

x = 88
def func():
    global x
    x = 99

func()
print(x)

99

在這個(gè)例子中,我們對(duì)X加了一個(gè)global聲明,以便在def之內(nèi)引用并修改位于全局的變量x,而不是產(chǎn)生一個(gè)新的本地變量x并將其覆蓋

我們?cè)倏匆粋€(gè)綜合的例子,串聯(lián)起剛剛我們提到的幾個(gè)知識(shí)點(diǎn)

x,y,z = 1,2,3

def all_global():
    global x
    x = y + z

all_global()
print(x)

5

這個(gè)例子中,x,y,z都是全局變量,y和z只是引用值,而對(duì)于x,我們想改變他的值,因此用了global進(jìn)行引用聲明。

【妹子說(shuō)】恩,作用域的內(nèi)容也是不少呀,LEGB,本地作用域、全局作用域、內(nèi)置作用域,包括他們的引用索引順序,但是好像掉了一條吧。

對(duì),還有嵌套作用域,這個(gè)是一個(gè)更加pythonic的內(nèi)容,我們下一節(jié)單獨(dú)花一節(jié)的篇幅進(jìn)行介紹。


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多