Python——函數(shù)作用域

Python作用域基礎(chǔ)

當(dāng)在程序中使用變量名時(shí)郑什,Python創(chuàng)建怠李、改變或查找變量名都是在所謂的命名空間中進(jìn)行的落塑。作用域這個(gè)術(shù)語指的就是命名空間弥奸。在代碼中變量名被賦值的位置決定了變量名能被訪問到的范圍

  • 所有的變量名榨惠,包括作用域的定義在內(nèi),都是Python賦值的時(shí)候生成的其爵。Python中的變量名在第一次賦值時(shí)已經(jīng)創(chuàng)建冒冬,并且必須經(jīng)過賦值后才能使用。
  • 在代碼中給一個(gè)變量賦值的地方?jīng)Q定了這個(gè)變量將存在哪個(gè)命名空間摩渺,也就是可見范圍

函數(shù)的作用域

  • 在默認(rèn)情況下简烤,一個(gè)函數(shù)的所有變量名都是與函數(shù)的命名空間相關(guān)聯(lián)的
    * 一個(gè)在def內(nèi)定義的變量名能夠被def內(nèi)的代碼使用,不能再函數(shù)的外部引用這樣的變量名
    * def之中的變量名與def之外的變量名并不沖突摇幻,即使變量名相同也不會(huì)沖突横侦。一個(gè)在def之外被賦值的變量x與在這個(gè)def之中的賦值的變量x時(shí)完全不同的變量

  • 如果一個(gè)變量在def內(nèi)賦值,則它被定位在這個(gè)函數(shù)之內(nèi)

  • 如果一個(gè)變量在一個(gè)嵌套def中賦值绰姻,則對(duì)于嵌套函數(shù)來說枉侧,它是非本地的

  • 如果在def之外賦值,它就是整個(gè)文件全局的

作用域法則

  • 函數(shù)定義了本地作用域狂芋,模塊定義了全局作用域
    * 內(nèi)嵌的模塊是全局作用域榨馁,每個(gè)模塊都是一個(gè)全局作用域。
    * 全局作用域的作用范圍僅限于單個(gè)文件帜矾,是指在一個(gè)文件的頂層的變量名僅對(duì)于這個(gè)文件內(nèi)部的代碼而言是全局的翼虫。必須精確的導(dǎo)入一個(gè)模塊文件才能夠使用這個(gè)文件中定義的變量名
    * 每次對(duì)函數(shù)的調(diào)用都創(chuàng)建了一個(gè)新的本地作用域屑柔,函數(shù)只要被調(diào)用,就會(huì)重新創(chuàng)建函數(shù)內(nèi)的本地作用域
    * 賦值的變量名除非聲明為全局變量或非本地變量否則均為本地變量珍剑。默認(rèn)情況下掸宛,所有函數(shù)定義內(nèi)部的變量都是本地作用域。
    * 如果需要給一個(gè)在函數(shù)內(nèi)部卻位于模塊文件頂層的變量名賦值招拙,需要在函數(shù)內(nèi)部通過global語句聲明
    * 如果需要給位于一個(gè)嵌套的def中的名稱賦值唧瘾,在Python3.0開始可以通過在一條nonlocal語句中聲明

作用域的產(chǎn)生

在Python中,只有函數(shù)(def) 類(class) 模塊(module)才會(huì)引入新的作用域别凤,其他的代碼塊不會(huì)產(chǎn)生新的作用域

變量名解析:LEGB原則

  • L local 函數(shù)中定義的變量
  • E enclosing 嵌套的父級(jí)函數(shù)的局部作用域饰序,即包含此函數(shù)的上級(jí)函數(shù)的局部作用域,但不是全局的闻妓;
  • G global 全局變量 模塊級(jí)別定義的變量
  • B built-in 系統(tǒng)固定模塊里面的變量菌羽,比如int, bytearray等
    **Python搜索變量的作用域的優(yōu)先級(jí)是:局部作用域>嵌套作用域>全局變量作用域>內(nèi)置作用域
    對(duì)于一個(gè)def語句
  • 變量名引用分為四個(gè)作用域進(jìn)行查找:首先是本地作用域(L),之后是上一層結(jié)構(gòu)中的def或lambda的本地作用域(E),然后是全局作用域(G)由缆,最后是Python內(nèi)置作用域(B)注祖,在找到這個(gè)變量名后會(huì)停止搜索,如果沒有找到會(huì)報(bào)錯(cuò)
  • 在默認(rèn)情況下均唉,變量名賦值會(huì)創(chuàng)建或者改變本地變量
  • 全局聲明和非本地聲明將賦值的變量名映射到模塊文件內(nèi)部的作用域
>>> # Global scope
>>> X = 99
>>> def func(Y):
...     Z=X+Y
...     return Z 
>>> fun(1)
>>> func(1)
100

內(nèi)置作用域

  • 內(nèi)置作用域僅僅是一個(gè)名為builtin的內(nèi)置模塊是晨,但是必須要導(dǎo)入后才能使用內(nèi)置作用域
  • 內(nèi)置作用域是通過一個(gè)名為builtin的標(biāo)準(zhǔn)庫(kù)模塊來實(shí)現(xiàn)的,沒有放置在作用域內(nèi)舔箭,必須導(dǎo)入這個(gè)文件才能使用
LEGB 存在的問題

由于LEGB查找的流程罩缴,會(huì)使它在找到第一處變量名的地方生效,在本地作用域的變量名可能會(huì)覆蓋在全局作用域和內(nèi)置作用域的有著相同變量名的變量层扶。全局變量名可能副高內(nèi)置的變量名

  • 如果在def內(nèi)不增加global(nonlocal)聲明的話箫章,是沒有辦法在函數(shù)內(nèi)改變函數(shù)外部的變量

locals() globals()

  • locals() 返回一個(gè)局部命名空間內(nèi)容的字典
  • globals() 返回一個(gè)全局命名空間內(nèi)容的字典
>>> animal = 'fruitbat'
>>> def change_local():
...     animal = 'wombat'
...     print('locals',locals())
... 
>>> animal
'fruitbat'
>>> change_local()
locals {'animal': 'wombat'}
>>> print('globals',globals())
globals {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': 
>>> animal
'fruitbat'

名稱中 _用法

Python中以兩個(gè)下劃線__開頭和結(jié)束的名稱都是Python的保留用法。因此在自定義的變量中不能使用它們

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末镜会,一起剝皮案震驚了整個(gè)濱河市檬寂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戳表,老刑警劉巖桶至,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匾旭,居然都是意外死亡镣屹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門价涝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來女蜈,“玉大人,你說我怎么就攤上這事∥苯眩” “怎么了吏廉?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)惰许。 經(jīng)常有香客問我,道長(zhǎng)史辙,這世上最難降的妖魔是什么汹买? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮聊倔,結(jié)果婚禮上晦毙,老公的妹妹穿的比我還像新娘。我一直安慰自己耙蔑,他們只是感情好见妒,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著甸陌,像睡著了一般须揣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上钱豁,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天耻卡,我揣著相機(jī)與錄音,去河邊找鬼牲尺。 笑死卵酪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的谤碳。 我是一名探鬼主播溃卡,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蜒简!你這毒婦竟也來了瘸羡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤臭蚁,失蹤者是張志新(化名)和其女友劉穎最铁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垮兑,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冷尉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了系枪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雀哨。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雾棺,到底是詐尸還是另有隱情膊夹,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布捌浩,位于F島的核電站放刨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏尸饺。R本人自食惡果不足惜进统,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望浪听。 院中可真熱鬧螟碎,春花似錦、人聲如沸迹栓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽克伊。三九已至酥郭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間答毫,已是汗流浹背褥民。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留洗搂,地道東北人消返。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耘拇,于是被迫代替她去往敵國(guó)和親撵颊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容