日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Python3 命名空間和作用域

Python3 命名空間和作用域

命名空間

先看看官方文檔的一段話:

A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。

命名空間(Namespace)是從名稱到對象的映射,大部分的命名空間都是通過 Python 字典來實(shí)現(xiàn)的。

命名空間提供了在項(xiàng)目中避免名字沖突的一種方法。各個命名空間是獨(dú)立的,沒有任何關(guān)系的,所以一個命名空間中不能有重名,但不同的命名空間是可以重名而沒有任何影響。

我們舉一個計算機(jī)系統(tǒng)中的例子,一個文件夾(目錄)中可以包含多個文件夾,每個文件夾中不能有相同的文件名,但不同文件夾中的文件可以重名。

一般有三種命名空間:

  • 內(nèi)置名稱(built-in names), Python 語言內(nèi)置的名稱,比如函數(shù)名 abs、char 和異常名稱 BaseException、Exception 等等。
  • 全局名稱(global names),模塊中定義的名稱,記錄了模塊的變量,包括函數(shù)、類、其它導(dǎo)入的模塊、模塊級的變量和常量。
  • 局部名稱(local names),函數(shù)中定義的名稱,記錄了函數(shù)的變量,包括函數(shù)的參數(shù)和局部定義的變量。(類中定義的也是)

命名空間查找順序:

假設(shè)我們要使用變量 runoob,則 Python 的查找順序?yàn)椋?strong>局部的命名空間 -> 全局命名空間 -> 內(nèi)置命名空間。

如果找不到變量 runoob,它將放棄查找并引發(fā)一個 NameError 異常:

NameError: name 'runoob' is not defined。

命名空間的生命周期:

命名空間的生命周期取決于對象的作用域,如果對象執(zhí)行完成,則該命名空間的生命周期就結(jié)束。

因此,我們無法從外部命名空間訪問內(nèi)部命名空間的對象。

實(shí)例

# var1 是全局名稱

var1
=
5


def some_func
(
):

 

   
# var2 是局部名稱

    var2
=
6

   
def some_inner_func
(
):

 

       
# var3 是內(nèi)嵌的局部名稱

        var3
=
7

如下圖所示,相同的對象名稱可以存在于多個命名空間中。


作用域

A scope is a textual region of a Python program where a namespace is directly accessible. "Directly accessible" here means that an unqualified reference to a name attempts to find the name in the namespace.

作用域就是一個 Python 程序可以直接訪問命名空間的正文區(qū)域。

在一個 python 程序中,直接訪問一個變量,會從內(nèi)到外依次訪問所有的作用域直到找到,否則會報未定義的錯誤。

Python 中,程序的變量并不是在哪個位置都可以訪問的,訪問權(quán)限決定于這個變量是在哪里賦值的。

變量的作用域決定了在哪一部分程序可以訪問哪個特定的變量名稱。Python 的作用域一共有4種,分別是:

有四種作用域:

  • L(Local):最內(nèi)層,包含局部變量,比如一個函數(shù)/方法內(nèi)部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個嵌套函數(shù),一個函數(shù)(或類) A 里面又包含了一個函數(shù) B ,那么對于 B 中的名稱來說 A 中的作用域就為 nonlocal。
  • G(Global):當(dāng)前腳本的最外層,比如當(dāng)前模塊的全局變量。
  • B(Built-in): 包含了內(nèi)建的變量/關(guān)鍵字等,最后被搜索。

規(guī)則順序: L –> E –> G –> B。

在局部找不到,便會去局部外的局部找(例如閉包),再找不到就會去全局找,再者去內(nèi)置中找。

g_count = 0  # 全局作用域
def outer():
    o_count = 1  # 閉包函數(shù)外的函數(shù)中
    def inner():
        i_count = 2  # 局部作用域

內(nèi)置作用域是通過一個名為 builtin 的標(biāo)準(zhǔn)模塊來實(shí)現(xiàn)的,但是這個變量名自身并沒有放入內(nèi)置作用域內(nèi),所以必須導(dǎo)入這個文件才能夠使用它。在Python3.0中,可以使用以下的代碼來查看到底預(yù)定義了哪些變量:

>>> import builtins
>>> dir(builtins)

Python 中只有模塊(module),類(class)以及函數(shù)(def、lambda)才會引入新的作用域,其它的代碼塊(如 if/elif/else/、try/except、for/while等)是不會引入新的作用域的,也就是說這些語句內(nèi)定義的變量,外部也可以訪問,如下代碼:

>>> if True:
...  msg = 'I am from Runoob'
... 
>>> msg
'I am from Runoob'
>>> 

實(shí)例中 msg 變量定義在 if 語句塊中,但外部還是可以訪問的。

如果將 msg 定義在函數(shù)中,則它就是局部變量,外部不能訪問:

>>> def test():
...     msg_inner = 'I am from Runoob'
... 
>>> msg_inner
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'msg_inner' is not defined
>>> 

從報錯的信息上看,說明了 msg_inner 未定義,無法使用,因?yàn)樗蔷植孔兞?,只有在函?shù)內(nèi)可以使用。

全局變量和局部變量

定義在函數(shù)內(nèi)部的變量擁有一個局部作用域,定義在函數(shù)外的擁有全局作用域。

局部變量只能在其被聲明的函數(shù)內(nèi)部訪問,而全局變量可以在整個程序范圍內(nèi)訪問。調(diào)用函數(shù)時,所有在函數(shù)內(nèi)聲明的變量名稱都將被加入到作用域中。如下實(shí)例:

實(shí)例(Python 3.0+)

#!/usr/bin/python3

total
=
0

# 這是一個全局變量

# 可寫函數(shù)說明

def

sum
(

arg1
,
arg2

)
:
#返回2個參數(shù)的和."

total
=
arg1
+
arg2

# total在這里是局部變量.

print

(
"
函數(shù)內(nèi)是局部變量 :
"
,
total
)

return

total

#調(diào)用sum函數(shù)

sum
(

10
,
20

)

print

(
"
函數(shù)外是全局變量 :
"
,
total
)

以上實(shí)例輸出結(jié)果:

函數(shù)內(nèi)是局部變量 :  30
函數(shù)外是全局變量 :  0

global 和 nonlocal關(guān)鍵字

當(dāng)內(nèi)部作用域想修改外部作用域的變量時,就要用到 global 和 nonlocal 關(guān)鍵字了。

以下實(shí)例修改全局變量 num:

實(shí)例(Python 3.0+)

#!/usr/bin/python3

num
=
1

def

fun1
(
)
:
global

num

# 需要使用 global 關(guān)鍵字聲明

print
(
num
)

num
=
123

print
(
num
)

fun1
(
)

print
(
num
)

以上實(shí)例輸出結(jié)果:

1
123
123

如果要修改嵌套作用域(enclosing 作用域,外層非全局作用域)中的變量則需要 nonlocal 關(guān)鍵字了,如下實(shí)例:

實(shí)例(Python 3.0+)

#!/usr/bin/python3

def

outer
(
)
:
num
=
10

def

inner
(
)
:
nonlocal

num

# nonlocal關(guān)鍵字聲明

num
=
100

print
(
num
)

inner
(
)

print
(
num
)

outer
(
)

以上實(shí)例輸出結(jié)果:

100
100

另外有一種特殊情況,假設(shè)下面這段代碼被運(yùn)行:

實(shí)例(Python 3.0+)

#!/usr/bin/python3

a
=
10

def

test
(
)
:
a
=
a
+
1

print
(
a
)

test
(
)

以上程序執(zhí)行,報錯信息如下:

Traceback (most recent call last):
  File "test.py", line 7, in 
    test()
  File "test.py", line 5, in test
    a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment

錯誤信息為局部作用域引用錯誤,因?yàn)?test 函數(shù)中的 a 使用的是局部,未定義,無法修改。

修改 a 為全局變量:

實(shí)例

#!/usr/bin/python3

a
=
10

def

test
(
)
:
global

a

a
=
a
+
1

print
(
a
)

test
(
)

執(zhí)行輸出結(jié)果為:

11

也可以通過函數(shù)參數(shù)傳遞:

實(shí)例(Python 3.0+)

#!/usr/bin/python3

a
=
10

def

test
(
a
)
:
a
=
a
+
1

print
(
a
)

test
(
a
)

執(zhí)行輸出結(jié)果為:

11


當(dāng)前文章:Python3 命名空間和作用域
當(dāng)前鏈接:http://www.dlmjj.cn/article/djiidej.html