九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
第22天:Python NameSpace & Scope

命名空間定義了在某個(gè)作用域內(nèi)變量名和綁定值之間的對(duì)應(yīng)關(guān)系,命名空間是鍵值對(duì)的集合,變量名與值是一一對(duì)應(yīng)關(guān)系。作用域定義了命名空間中的變量能夠在多大范圍內(nèi)起作用。

命名空間在python解釋器中是以字典的形式存在的,是以一種可以看得見(jiàn)摸得著的實(shí)體存在的。作用域是python解釋器定義的一種規(guī)則,該規(guī)則確定了運(yùn)行時(shí)變量查找的順序,是一種形而上的虛的規(guī)定。

一、命名空間

1、概述

A namespace is a mapping from names to objects.Most namespaces are currently implemented as Python dictionaries。
命名空間是名字和對(duì)象的映射,命名空間是通過(guò) Python Dictionary(字典) 來(lái)實(shí)現(xiàn)的。

  • 命名空間提供了一個(gè)在大型項(xiàng)目下避免名字沖突的方法

  • Python 中各個(gè)命名空間都是獨(dú)立的,他們之間無(wú)任何關(guān)系

  • 一個(gè)命名空間中不能有重名,但不同的命名空間是可以重名而沒(méi)有任何影響。

命名空間就像是計(jì)算機(jī)中的文件夾一樣,同一個(gè)文件夾中的文件不可重名,但是如果兩個(gè)文件從屬于不同的文件夾就可以重名。

同理相同的對(duì)象名可以存在不同的命名空間中:

2、命名空間種類(lèi)

命名空間的種類(lèi)分為 3 類(lèi),命名空間的種類(lèi)也體現(xiàn)了命名空間的生命周期。三個(gè)種類(lèi)及生命周期描述如下:

1)內(nèi)置名稱(chēng)(built-in names)

Python 語(yǔ)言內(nèi)置的名稱(chēng),比如函數(shù)名 abs、char 和異常名稱(chēng) BaseException、Exception 等等。

生命周期:

對(duì)于Python built-in names組成的命名空間,它在Python解釋器啟動(dòng)的時(shí)候被創(chuàng)建,在解釋器退出的時(shí)候才被刪除;

2)全局名稱(chēng)(global names)

模塊中定義的名稱(chēng),記錄了模塊的變量,包括函數(shù)、類(lèi)、其它導(dǎo)入的模塊、模塊級(jí)的變量和常量。

生命周期:

對(duì)于一個(gè)Python模塊的global namespace,它在這個(gè)module被import的時(shí)候創(chuàng)建,在解釋器退出的時(shí)候退出;

3)局部名稱(chēng)(local names)

函數(shù)中定義的名稱(chēng),記錄了函數(shù)的變量,包括函數(shù)的參數(shù)和局部定義的變量。(類(lèi)中定義的也是)

生命周期:

對(duì)于一個(gè)函數(shù)的local namespace,它在函數(shù)每次被調(diào)用的時(shí)候創(chuàng)建,函數(shù)返回的時(shí)候被刪除。

注意:命名空間的生命周期取決于對(duì)象的作用域,如果對(duì)象執(zhí)行完成,則該命名空間的生命周期就結(jié)束。因此,我們無(wú)法從外部命名空間訪問(wèn)內(nèi)部命名空間的對(duì)象。例如:

  1. # var1 是全局名稱(chēng)

  2. var1 = 5

  3. def some_func():

  4. # var2 是局部名稱(chēng)

  5. var2 = 6

  6. def some_inner_func():

  7. # var3 是內(nèi)嵌的局部名稱(chēng)

  8. var3 = 7

命名空間分類(lèi)圖如下:

3、命名空間查找、創(chuàng)建、銷(xiāo)毀順序

3.1 查找變量

如果程序執(zhí)行時(shí)去使用一個(gè)變量 hello ,那么 Python, 查找變量順序?yàn)椋?/p>

局部的命名空間 -> 全局命名空間 -> 內(nèi)置命名空間

如果按照這個(gè)順序找不到相應(yīng)的變量,它將放棄查找并拋出一個(gè) NameError 異常:

  1. NameError: name 'hello' is not defined。

3.2 各命名空間創(chuàng)建順序:

python解釋器啟動(dòng) ->創(chuàng)建內(nèi)建命名空間 -> 加載模塊 -> 創(chuàng)建全局命名空間 ->函數(shù)被調(diào)用 ->創(chuàng)建局部命名空間

3.3 各命名空間銷(xiāo)毀順序:

函數(shù)調(diào)用結(jié)束 -> 銷(xiāo)毀函數(shù)對(duì)應(yīng)的局部命名空間 -> python虛擬機(jī)(解釋器)退出 ->銷(xiāo)毀全局命名空間 ->銷(xiāo)毀內(nèi)建命名空間

4、命名空間總結(jié)

一個(gè)模塊的引入,函數(shù)的調(diào)用,類(lèi)的定義都會(huì)引入命名空間,函數(shù)中的再定義函數(shù),類(lèi)中的成員函數(shù)定義會(huì)在局部namespace中再次引入局部namespace。

二、作用域

1、概述

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.

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

  • Python 程序中,直接訪問(wèn)一個(gè)變量,會(huì)從內(nèi)到外依次訪問(wèn)所有的作用域直到找到,否則會(huì)報(bào)未定義的錯(cuò)誤。

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

  • Python 中, 變量的作用域決定了在哪一部分程序可以訪問(wèn)哪個(gè)特定的變量名稱(chēng)

2、作用域種類(lèi)

作用域分為4類(lèi),分別如下:

  • L(Local):最內(nèi)層,包含局部變量,比如一個(gè)函數(shù)/方法內(nèi)部。

  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的變量。比如兩個(gè)嵌套函數(shù),一個(gè)函數(shù)(或類(lèi)) A 里面又包含了一個(gè)函數(shù) B ,那么對(duì)于 B 中的名稱(chēng)來(lái)說(shuō) A 中的作用域就為 nonlocal。

  • G(Global):當(dāng)前腳本的最外層,比如當(dāng)前模塊的全局變量。

  • B(Built-in):包含了內(nèi)建的變量/關(guān)鍵字等,最后被搜索。

作用域規(guī)則順序?yàn)椋篖->E->G->B 如果變量在局部?jī)?nèi)找不到,便會(huì)去局部外的局部找(例如閉包),再找不到就會(huì)去全局找,再找不到就去內(nèi)置中找,如下圖所示:

3、全局作用域和局部作用域

局部作用域 (Local)是腳本中的最內(nèi)層,包含局部變量,比如一個(gè)函數(shù)或方法內(nèi)部。閉包函數(shù)外函數(shù)(Enclosing)包含了非局部(non-local)也非全局(non-global)的變量。全局作用域(Global)是當(dāng)前腳本的最外層,如當(dāng)前模塊的全局變量,實(shí)例如下:

  1. global_scope = 0 # 全局作用域

  2. # 定義閉包函數(shù)中的局部作用域

  3. def outer():

  4. o_count = 1 # 閉包函數(shù)外的函數(shù)中,相對(duì)于函數(shù) inner() 來(lái)說(shuō) 作用域非局部

  5. def inner():

  6. local_scope = 2 # 局部作用域

以上實(shí)例展示的是全局作用域和閉包函數(shù)中的函數(shù),以及函數(shù)中的局部作用域,對(duì)于函數(shù) inner() 來(lái)說(shuō),outer() 中的作用域?yàn)?non-local

4、內(nèi)建作用域

Python 中的內(nèi)建作用域(Built-in):包含了內(nèi)建的變量/關(guān)鍵字等,最后被搜索

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

  1. import builtins

  2. dir(builtins)

  3. ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError'...]

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

  1. name1 = 'SuSan'

  2. if chr('SuSan'.__eq__(name1)):

  3. result = 'I am from China'

  4. else:

  5. result = 'I am from USA'

  6. print(result)

  7. # 輸出結(jié)果為:

  8. I am SuSan,I am from China

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

如果將 result 定義在函數(shù)中,則它就是局部變量,外部不能訪問(wèn),在代碼中會(huì)報(bào)錯(cuò)運(yùn)行出異常:

  1. # 如果將變量定義在函數(shù)內(nèi)部,則外部不能訪問(wèn)

  2. def names():

  3. name2 = 'SuSan'

  4. # 在程序調(diào)用方法內(nèi)部的變量報(bào)錯(cuò)

  5. if('SuSan'.__eq__(name2)):

  6. result = 'I am '+name2 +','+'I am from China'

  7. else:

  8. result = 'I am from USA'

  9. print(result)

  10. #運(yùn)行輸出異常

  11. Traceback (most recent call last):

  12. File "python_scope.py", line 30, in <module>

  13. if('SuSan'.__eq__(name1)):

  14. NameError: name 'name2' is not defined

從以上報(bào)錯(cuò)信息看出,name2 未定義,因?yàn)閚ame2 是函數(shù)names() 中的局部變量,只能在函數(shù)內(nèi)部調(diào)用,外部不能調(diào)用函數(shù)中的局部變量。

5、全局變量和局部變量

  • 全局變量:定義在函數(shù)外部擁有全局作用域的變量

  • 局部變量:定義在函數(shù)內(nèi)部擁有局部作用域的變量

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

  1. # 全局變量和局部變量

  2. total = 0 # 這是一個(gè)全局變量

  3. # 函數(shù)說(shuō)明

  4. def sum(arg1, arg2):

  5. # 返回2個(gè)參數(shù)的和."

  6. total = arg1 + arg2 # total在這里是局部變量.

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

  8. return total

  9. # 調(diào)用sum函數(shù),傳入?yún)?shù)的計(jì)算結(jié)果顯示局部變量

  10. sum(10, 20)

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

  12. # 輸出結(jié)果為:

  13. 函數(shù)內(nèi)是局部變量 : 30

  14. 函數(shù)外是全局變量 : 0

6、global 和 nonlocal關(guān)鍵字

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

變量訪問(wèn)順序
當(dāng)前作用域局部變量->外層作用域變量->再外層作用域變量->......->當(dāng)前模塊全局變量->pyhton內(nèi)置變量

  • global:全局變量,當(dāng)局部作用域改變?nèi)肿兞坑胓lobal,同時(shí)global還可以定義新的全局變量

  • nonlocal:外層嵌套函數(shù)的變量,nonlocal不能定義新的外層函數(shù)變量,只能改變已有的外層函數(shù)變量,同時(shí)nonlocal不能改變?nèi)肿兞?/span>

6.1 修改全局變量

  1. num = 1

  2. def fun1():

  3. # 申明訪問(wèn)全局變量

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

  5. # 輸出全局變量原始值

  6. print(num)

  7. # 修改全局變量

  8. num = 123

  9. print(num)

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

  11. fun1()

  12. # 輸出修改后的全局變量值

  13. print(num)

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

  1. 1

  2. 123

  3. 123

6.2 修改嵌套作用域

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

  1. # 定義函數(shù)

  2. def outer():

  3. # 定義變量

  4. num = 10

  5. # 定義嵌套函數(shù)

  6. def inner():

  7. nonlocal num # nonlocal關(guān)鍵字聲明,使用函數(shù)中變量

  8. # 修改變量值

  9. num = 100

  10. print(num)

  11. inner()

  12. print(num)

  13. outer()

以上實(shí)例輸出:

  1. 100

  2. 100

另外還有一種特殊情況,以下這段代碼有語(yǔ)法錯(cuò)誤,運(yùn)行會(huì)報(bào)一個(gè)異常:

  1. b = 8

  2. def test():

  3. b = b * 10

  4. print(b)

  5. test()

  6. # 異常信息:UnboundLocalError

程序執(zhí)行異常:

  1. Traceback (most recent call last):

  2. File "python_scope.py", line 90, in <module>

  3. test()

  4. File "python_scope.py", line 88, in test

  5. a = a + 1

  6. UnboundLocalError: local variable 'a' referenced before assignment

錯(cuò)誤信息為局部作用域引用錯(cuò)誤,因?yàn)?test 函數(shù)中的 a 使用的是局部變量,未定義,無(wú)法修改。將 a 修改為全局變量,通過(guò)函數(shù)參數(shù)傳遞,程序就可以正常執(zhí)行,輸出結(jié)果為:

  1. b = 8

  2. def test(b):

  3. b = b * 10

  4. print(b)

  5. test(b)

程序輸出結(jié)果為:

  1. 80

另一種解決辦法是加 global 關(guān)鍵字:

  1. b = 8

  2. def test():

  3. global b

  4. b = b * 30

  5. print(b)

  6. test()

輸出結(jié)果為:

  1. 240

6.3 global 和 nonlocal 的區(qū)別

  • 兩者的功能不同。global關(guān)鍵字修飾變量后標(biāo)識(shí)該變量是全局變量,對(duì)該變量進(jìn)行修改就是修改全局變量,而nonlocal關(guān)鍵字修飾變量后標(biāo)識(shí)該變量是上一級(jí)函數(shù)中的局部變量,如果上一級(jí)函數(shù)中不存在該局部變量,nonlocal位置會(huì)發(fā)生錯(cuò)誤(最上層的函數(shù)使用nonlocal修飾變量必定會(huì)報(bào)錯(cuò))。

  • 兩者使用的范圍不同。global關(guān)鍵字可以用在任何地方,包括最上層函數(shù)中和嵌套函數(shù)中,即使之前未定義該變量,global修飾后也可以直接使用,而nonlocal關(guān)鍵字只能用于嵌套函數(shù)中,并且外層函數(shù)中定義了相應(yīng)的局部變量,否則會(huì)發(fā)生錯(cuò)誤

總結(jié)

本節(jié)給大家介紹了 Python 命名空間和作用用戶的介紹與簡(jiǎn)單應(yīng)用,在 Python 開(kāi)發(fā)實(shí)戰(zhàn)中對(duì)命名空間和作用域的運(yùn)用比較廣泛,謹(jǐn)以此文獻(xiàn)給在 Python 學(xué)習(xí)道路上的道友,希望對(duì)大家有一絲幫助。

參考:

https://www.runoob.com/python3/python3-namespace-scope.html

系列文章

          LeetCode面試系列 第4天:No.202 - 快樂(lè)數(shù)


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
python global、locals()、nonlocal
這一篇把Python 作用域的疑惑終于解決了
初識(shí) Python:全局、局部和非局部變量(帶示例) | Linux 中國(guó)
Python函數(shù)式編程
python的名稱(chēng)空間和作用域
Python中的變量作用域總結(jié)
更多類(lèi)似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服