成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

python基礎(chǔ)教程:作用域和命名空間

wangzy2019 / 1830人閱讀

摘要:正如我們前面舉的張三的例子那樣,不同命名空間中的名稱之間沒有任何關(guān)系。作用域作用域,是一個命名空間可直接發(fā)放完的代碼的文本區(qū)域。刪除也是如此,語句會從局部命名空間的引用中移除對的綁定。

命名空間和作用域的概念我們之前也提到過,比如內(nèi)置函數(shù)globals(),函數(shù)中變量的作用域,模塊使用的import等等。這些可能讓我們對這兩個概念有了大致的理解。本節(jié)再詳細探討一下。

Python命名空間

命名空間,就是一個從名稱到對象的映射關(guān)系。

對于這個概念的理解,我們打個比方:河西村有個人(對象)叫張三(名稱),河?xùn)|村有個人(對象)也叫張三(名稱),倆人雖然都叫張三(名稱),但是他們倆不是同一個人(對象),因為他們屬于不同的村(命名空間)。有一天,河西村的張三名聲大了,傳播到鎮(zhèn)上了(名稱被import到“鎮(zhèn)”這個空間),鎮(zhèn)上的人講起“張三”時,就是說的河西村的,要是說河?xùn)|村的張三,就要特別說“河?xùn)|村的張三”(河?xùn)|村.張三)。這就是命名空間的意思——映射了名稱到對象的名稱范圍。

目前,大部分的命名空間都是由Python的字典實現(xiàn)的,通常我們不會去關(guān)注它們,處理要面對性能問題時,并且這種實現(xiàn)可能在將來改變。所以說,我們不需要深究命名空間的內(nèi)部實現(xiàn),但要搞明白它的使用。

下面是幾個命名空間的例子:

內(nèi)置函數(shù)的集合(包含print()等內(nèi)置函數(shù)和內(nèi)置異常等);

模塊中的全局名稱;

函數(shù)調(diào)用中的本地名稱。

另外,從某種含義上說,對象的屬性集合也是一種命名空間的形式。正如我們前面舉的張三的例子那樣,不同命名空間中的名稱之間沒有任何關(guān)系。比如,兩個不同模塊都可以定義函數(shù)max()而不會產(chǎn)生混淆,模塊的用戶要調(diào)用某個max()函數(shù)就要在其前面加上模塊名稱。(詳見import的使用)

Python屬性

我們把任何跟在一個點號之后的名稱都稱為屬性。例如,在表達式a.name中,real是對象a的一個屬性。同樣對模塊中函數(shù)的引用也是屬性引用,在表達式modname.funcname中,modname是一個模塊對象,而funcname是它的一個屬性。

屬性可以是只讀的也可以是可寫的。如果是可寫的,那么我們就可以對屬性進行賦值,比如,modname.name = "猿人學(xué)Python"??蓪懙膶傩酝瑯涌梢杂?b>del語句刪除,比如del modname.name將把modname對象的name屬性移除。

不同時刻創(chuàng)建的命名空間有不同的生存期:

包含內(nèi)置名稱的命名空間是在Python解釋器啟動時創(chuàng)建的,永遠不會被刪除(除非退出解釋器);

模塊的全局命名空間在模塊定義被讀入(import)時創(chuàng)建,通常,模塊命名空間也會持續(xù)到解釋器退出;

從腳本文件(.py.pyc)讀取或交互式(解釋器shell)讀取而被解釋器的頂層調(diào)用執(zhí)行的語句,被認為是__main__模塊調(diào)用的一部分,它們有自己的全局命名空間;

函數(shù)的本地命名空間創(chuàng)建于該函數(shù)被調(diào)用的時刻,并且在函數(shù)返回或拋出一個不在函數(shù)內(nèi)部處理的異常時被刪除。遞歸函數(shù)的每次遞歸調(diào)用都會創(chuàng)建它自己的本地命名空間;

內(nèi)置名稱實際上也存在于一個模塊中,它叫做builtins。

Python作用域

作用域,是一個命名空間可直接發(fā)放完的Python代碼的文本區(qū)域。這里的“可直接訪問”的意思是,對名稱的不加點號(非限定性)引用會嘗試在命名空間中查找該名稱。

盡管作用域是靜態(tài)確定的,但它們是動態(tài)使用的。在執(zhí)行期間的任何時刻,至少有三個嵌套的作用域,它們的命名空間可以直接訪問:

最內(nèi)部作用域:最先搜索該作用域,包含局部名稱

封閉函數(shù)作用域:從最近的封閉作用域開始搜索,包含非局部名稱,也包括非全局名稱

倒數(shù)第二個作用域:包含當前模塊的全局名稱

最外面的作用域:最后搜索,是包含內(nèi)置名稱的命名空間

如果一個名稱被聲明為全局變量,則所有引用和賦值將直接指向包含該模塊的全局名稱的中間作用域。 要重新綁定在最內(nèi)層作用域以外找到的變量,可以使用nonlocal語句聲明為非本地變量。 如果沒有被聲明為非本地變量,這些變量將是只讀的(嘗試寫入這樣的變量只會在最內(nèi)層作用域中創(chuàng)建一個新的局部變量,而同名的外部變量保持不變)。

很重要的一點:作用域是按文本方式確定的,模塊內(nèi)定義的函數(shù)的全局作用域就是該模塊的命名空間,無論該函數(shù)從什么地方或以什么別名被調(diào)用。另一方面,實際的名稱搜索是在運行時動態(tài)完成的。

Python 的一個特殊之處在于: 如果不存在生效的global語句,對名稱的賦值總是進入最內(nèi)層作用域。 賦值不會復(fù)制數(shù)據(jù),它們只是將名稱綁定到對象。刪除也是如此,語句del x會從局部命名空間的引用中移除對x的綁定。事實上,所有引入新名稱的操作都使用局部作用域,特別是import語句和函數(shù)定義會在局部作用域中綁定模塊或函數(shù)名稱。

global語句可被用來表明特定變量生存于全局作用域并且應(yīng)當在其中被重新綁定;nonlocal語句表明特定變量生存于外層作用域中并且應(yīng)當在其中被重新綁定。

下面我們來看一個作用域和命名空間的例子,它演示流量如何引用不同作用域和命名空間以及globalnonlocal如何影響變量綁定:

def scope_demo():
    def do_local():
        name = "local name"

    def do_nonlocal():
        nonlocal name
        name = "nonlocal name"

    def do_global():
        global name
        name = "global name"

    name = "demo name"
    do_local()
    print("After local assignment:", name)
    do_nonlocal()
    print("After nonlocal assignment:", name)
    do_global()
    print("After global assignment:", name)

scope_demo()
print("In global scope:", name)

思考一下,上面的代碼會輸出怎樣的結(jié)果?如果你對上面的講解理解透了,你的思考結(jié)果應(yīng)該是這樣的:

After local assignment: demo name
After nonlocal assignment: nonlocal name
After global assignment: nonlocal name
In global scope: global name

這里要說明的是,do_global()函數(shù)修改了全局變量name,并沒有對scope_demo()函數(shù)的局部變量name做修改,所以打印了After global assignment: nonlocal name。

局部賦值(默認情況)不會改變scope_demoname的綁定;nonlocal賦值會改變函數(shù)scope_demoname的綁定,而global賦值會改變模塊層級的綁定(不是scope_demo內(nèi)部的name,而是其之外的全局作用域下的name)。

命令空間和作用域總結(jié):

命名空間定義了一個名稱的范圍,作用域指定了能看到命名空間的文本區(qū)域(代碼)。代碼執(zhí)行時,名稱搜索的順序和范圍如下:

最內(nèi)部作用域:最先搜索該作用域,包含局部名稱

封閉函數(shù)作用域:從最近的封閉作用域開始搜索,包含非局部名稱,也包括非全局名稱

倒數(shù)第二個作用域:包含當前模塊的全局名稱

最外面的作用域:最后搜索,是包含內(nèi)置名稱的命名空間

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/43845.html

相關(guān)文章

  • Python基礎(chǔ)教程

    摘要:函數(shù)內(nèi)的變量被稱為局部變量,這是與全局變量相反的概念。有一些進行函數(shù)式編程的機制。繼承以通用的類為基礎(chǔ)建立專門的類對象。 6.4.5 參數(shù)收集的逆過程 假設(shè)有如下函數(shù): def add(x,y): return x+y 比如說有個包含由兩個相加的數(shù)字組成的元組: params = (1,2) 使用*運算符對參數(shù)進行分配,不過是在調(diào)用而不是在定義時使用: >>> add(*params)...

    daydream 評論0 收藏0
  • python基礎(chǔ)教程:類

    摘要:類對象被創(chuàng)建時存在于類命名空間內(nèi)的所有名稱都是有效的屬性名稱。類的實例化,是使用函數(shù)表示法,可以把類對象看做是會返回一個新的類實例的函數(shù)。這就是可變對象作為類變量時的特性。類變量是所有類的實例共享的屬性和方法,實例變量是每個實例獨有的數(shù)據(jù)。 Python是面向?qū)ο蟮母呒壘幊陶Z言,在Python里面一切都是對象:數(shù)字、字符串、元組、列表、字典、集合等內(nèi)置數(shù)據(jù)類型,以及函數(shù)、方法、類、模塊...

    fish 評論0 收藏0
  • 一道題看Python的LEGB規(guī)則

    摘要:例題核心編程第二版變量作用域和命名空間一節(jié)有以下一道題目請問輸出結(jié)果是什么要想解這道題,必須先了解中的一些概念的變量名解析機制有時稱為。 例題 《核心編程(第二版)》變量作用域和命名空間一節(jié)有以下一道題目 # coding=utf-8 #!/usr/bin/env python def proc1(): j,k = 3,4 print j == %d and k ==...

    iamyoung001 評論0 收藏0
  • Python學(xué)習(xí)--最完整的基礎(chǔ)知識大全

    摘要:迭代器對象從集合的第一個元素開始訪問,直到所有的元素被訪問完結(jié)束。迭代器有兩個基本的方法和。調(diào)用一個生成器函數(shù),返回的是一個迭代器對象。生成器函數(shù)生成器函數(shù)返回一個迭代器函數(shù)函數(shù)傳入不定長參數(shù)加了星號的變量名會存放所有未命名的變量參數(shù)。 Python學(xué)習(xí)--最完整的基礎(chǔ)知識大全 關(guān)于python的基礎(chǔ)知識學(xué)習(xí),網(wǎng)上有很多資料,今天我就把我收藏的整理一下分享給大家! 菜鳥教程pytho...

    王笑朝 評論0 收藏0
  • Python基礎(chǔ)教程》第六章--讀書筆記

    摘要:第六章抽象本章會介紹如何將語句組織成函數(shù)。關(guān)鍵字參數(shù)和默認值目前為止,我們使用的參數(shù)都是位置參數(shù),因為它們的位置很重要,事實上比它們的名字更重要。參數(shù)前的星號將所有值放置在同一個元祖中。函數(shù)內(nèi)的變量被稱為局部變量。 第六章:抽象 本章會介紹如何將語句組織成函數(shù)。還會詳細介紹參數(shù)(parameter)和作用域(scope)的概念,以及遞歸的概念及其在程序中的用途。 懶惰即美德 斐波那契數(shù)...

    AnthonyHan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<