Python 基礎(chǔ)教程

Python 流程控制

Python 函數(shù)

Python 數(shù)據(jù)類型

Python 文件操作

Python 對(duì)象和類

Python 日期和時(shí)間

Python 高級(jí)知識(shí)

Python 參考手冊(cè)

Python 命名空間和作用域

在本文中,您將了解命名空間,從名稱到對(duì)象的映射以及變量的作用域。

Python中的命名空間是什么?

如果您曾經(jīng)讀過(guò)“ Python之禪(The Zen of Python) ”(在Python解釋器中輸入import this),最后一行指出,命名空間是一個(gè)很棒的主意-讓我們做更多的事情!那么這些神秘的命名空間是什么?首先讓我們看看名稱是什么。

名稱(也稱為標(biāo)識(shí)符)只是賦予對(duì)象的名稱。Python中的一切都是對(duì)象。名稱是訪問(wèn)基礎(chǔ)對(duì)象的一種方式。

例如,當(dāng)我們執(zhí)行賦值操作時(shí)a = 2,2是一個(gè)存儲(chǔ)在內(nèi)存中的對(duì)象,而a是與之關(guān)聯(lián)的名稱。我們可以通過(guò)內(nèi)置函數(shù) 獲取某些對(duì)象的地址(在RAM中)id()。讓我們看看如何使用它。

# 注意:您可能會(huì)得到不同的id值
a = 2
print('id(2) =', id(2))

print('id(a) =', id(a))

輸出結(jié)果

id(2) = 9302208
id(a) = 9302208

在這里,兩者都引用相同的對(duì)象2,因此它們具有相同的id()。讓我們做些有趣的事情。

# 注意:您可能會(huì)得到不同的id值

a = 2
print('id(a) =', id(a))

a = a+1
print('id(a) =', id(a))

print('id(3) =', id(3))

b = 2
print('id(b) =', id(b))
print('id(2) =', id(2))

輸出結(jié)果

id(a) = 9302208
id(a) = 9302240
id(3) = 9302240
id(b) = 9302208
id(2) = 9302208

上述步驟序列中發(fā)生了什么?讓我們用一個(gè)圖來(lái)解釋一下:

變量的內(nèi)存圖
Python中變量的內(nèi)存圖

最初,創(chuàng)建一個(gè)對(duì)象2并將名稱a與之相關(guān)聯(lián),當(dāng)我們執(zhí)行a = a + 1時(shí),將創(chuàng)建一個(gè)新的對(duì)象3,現(xiàn)在a與該對(duì)象相關(guān)聯(lián)。

請(qǐng)注意,id(a)和id(3)具有相同的值。

此外,當(dāng)執(zhí)行b = 2時(shí),新名稱b與先前的對(duì)象2相關(guān)聯(lián)。

這是有效的,因?yàn)镻ython不必創(chuàng)建新的重復(fù)對(duì)象。 名稱綁定的這種動(dòng)態(tài)特性使Python變得功能強(qiáng)大。 名稱可以引用任何類型的對(duì)象。

>>> a = 5
>>> a = 'Hello World!'
>>> a = [1,2,3]

所有這些都是有效的,并且a將在不同示例中引用三種不同類型的對(duì)象。函數(shù)也是對(duì)象,因此名稱也可以引用它們。

def printHello():
    print("Hello")


a = printHello

a()

輸出結(jié)果

Hello

相同的名稱a可以引用一個(gè)函數(shù),我們可以使用該名稱來(lái)調(diào)用該函數(shù)。

什么是Python中的命名空間?

現(xiàn)在我們了解了名稱是什么,我們可以繼續(xù)進(jìn)行命名空間的概念。

簡(jiǎn)而言之,命名空間是名稱的集合。

在Python中,您可以將命名空間想象為已定義的每個(gè)名稱到對(duì)應(yīng)對(duì)象的映射。

不同的命名空間可以在給定時(shí)間共存,但完全隔離。

當(dāng)我們啟動(dòng)Python解釋器時(shí),將創(chuàng)建一個(gè)包含所有內(nèi)置名稱的命名空間,并且只要該解釋器運(yùn)行,該命名空間就會(huì)存在。

這就是為什么內(nèi)置的功能(例如id())print()等始終可以從程序的任何部分使用的原因。每個(gè)模塊創(chuàng)建自己的全局命名空間。

這些不同的命名空間是隔離的。因此,不同模塊中可能存在的相同名稱不會(huì)沖突。

模塊可以具有各種功能和類。調(diào)用函數(shù)時(shí)會(huì)創(chuàng)建一個(gè)本地命名空間,其中定義了所有名稱。與類相似。下圖可能有助于闡明這一概念。

Python編程中的嵌套命名空間
Python中不同命名空間的圖

Python變量作用域

盡管定義了各種唯一的命名空間,但我們可能無(wú)法從程序的每個(gè)部分訪問(wèn)它們。作用域的概念開(kāi)始起作用。

作用域是程序的一部分,從那里可以直接訪問(wèn)命名空間而無(wú)需任何前綴。

在任何給定時(shí)刻,至少有三個(gè)嵌套作用域。

  1. 具有本地名稱的當(dāng)前函數(shù)的作用域

  2. 具有全局名稱的模塊的作用域

  3. 具有內(nèi)置名稱的最外部作用域

在函數(shù)內(nèi)部進(jìn)行引用時(shí),將在本地命名空間中搜索名稱,然后在全局命名空間中搜索,最后在內(nèi)置命名空間中搜索。

如果另一個(gè)函數(shù)內(nèi)有一個(gè)函數(shù),則新作用域嵌套在本地作用域內(nèi)。

Python作用域和命名空間的示例

def outer_function():
    b = 20
    def inner_func():
        c = 30

a = 10

在這里,變量a在全局命名空間中。變量b在的本地命名空間中,outer_function()而c在的嵌套本地命名空間中inner_function()。

當(dāng)我們?cè)跁r(shí)inner_function(),c在我們本地,b在非本地,a在全局。我們可以為c讀取和分配新值,但只能 從中讀取bainner_function()。

如果我們嘗試分配作為值b,一個(gè)新的變量b在本地命名空間比非本地不同的創(chuàng)建b。當(dāng)我們分配一個(gè)值,同樣的事情發(fā)生一個(gè)。

但是,如果我們將a聲明為全局a,則所有引用和賦值都將移至全局a。同樣,如果我們想重新綁定變量b,則必須將其聲明為非本地變量。以下示例將進(jìn)一步闡明這一點(diǎn)。

def outer_function():
    a = 20

    def inner_function():
        a = 30
        print('a =', a)

    inner_function()
    print('a =', a)


a = 10
outer_function()
print('a =', a)

正如您看到的,該程序的輸出為

a = 30
a = 20
a = 10

在此程序中,在不同的命名空間中定義了三個(gè)不同的變量a并進(jìn)行了相應(yīng)的訪問(wèn)。在以下程序中,

def outer_function():
    global a
    a = 20

    def inner_function():
        global a
        a = 30
        print('a =', a)

    inner_function()
    print('a =', a)


a = 10
outer_function()
print('a =', a)

程序的輸出是。

a = 30
a = 30
a = 30

在這里,由于使用了關(guān)鍵字global,所以所有引用和賦值都指向全局a。

丰满人妻一级特黄a大片,午夜无码免费福利一级,欧美亚洲精品在线,国产婷婷成人久久Av免费高清