模組 包 命名空間和作用域

2021-10-07 16:32:19 字數 1680 閱讀 5619

模組的物理層面是檔案,包就是有層次的特殊檔案結構,特殊的點在於,每個目錄下面都必須有__init__.py檔案,如果沒有該檔案,則只是乙個普通的檔案目錄,並不能作為包匯入。這是因為匯入包的原理其實就是匯入該包的路徑下面的__init__.py,其中包含可以匯入的各種模組。

**python模組的匯入操作

通過import、from import語句匯入乙個模組,或者通過as給模組起別名,模組只有在第一次匯入的時候才會被載入,模組載入時,其實就是執行模組中的所有語句,此時,如果模組中除了定義的類和方法之外,在全域性作用域下有**時,這些**會被執行,所以在模組編寫中需要避免在頂級作用域下直接執行**。

# a.py

print

'm'deff(

):print

'fm'

classa(

object):

print

'a.m'

deffa

(self)

:print

'a.f.m'

# b.py

import a

從b模組中匯入a,執行b,會輸出:

m

a.m

模組中的頂層變數會在模組匯入時就執行,類的類變數也是如此,因此在模組中應該盡量避免這種,放在函式中進行延遲生成。這裡需要深入了解模組的匯入機制。

在模組第一次被匯入時,往往會比較慢,這是因為python在匯入乙個新的模組時,會從模組所在目錄檢查是否有.pyc檔案,如果沒有該檔案,則會將模組編譯成位元組碼,從而提高下一次匯入的效率*。

python也可以從乙個zip檔案中匯入模組,該zip檔案會被看成乙個包,然而python不會再生成.pyc檔案到該zip檔案中,所以匯入效率相對較低一些。

命名空間(namespace)是從名稱到物件的對映,大部分的命名空間都是通過 python 字典來實現的。一般有三種命名空間:區域性命名空間、全域性命名空間、內建命名空間。內建命名空間的所有名字都包含在__builtins__模組中,該模組又包含__buitin__模組,該模組中包含內建函式、異常以及其他屬性,每乙個python程式執行之前都會先導入__builtins__模組,每個模組都有自己的命名空間,匯入乙個模組時,會載入執行模組的全域性命名空間,這也是為什麼在載入乙個模組時,所有全域性作用域下的**會直接執行。

在訪問乙個屬性的時候,會從區域性命名空間、全域性命名空間、內建命名空間中尋找該名字,如果都找不到則會返回乙個nameerror的錯誤,由於尋找時總是先去尋找區域性命名空間,所以區域性命名空間中如果有和全域性命名空間中的變數重名,則會講全域性命名空間中的變數被「覆蓋」*(其實是不會再被找到)。

python3 命名空間和作用域

變數的作用域決定了在哪一部分程式可以訪問哪個特定的變數名稱。

python變數作用域可以分為四種,分別為區域性作用域、巢狀作用域、全域性作用域、內建作用域。

所有區域性命名空間的名稱都在區域性作用範圍內,區域性命名空間之外的所有名稱都在全域性作用範圍內。區域性命名空間和作用域會隨著函式的呼叫而不斷變化,但是全域性命名空間是不變的。命名空間決定乙個變數名字是否存在,而作用域決定乙個變數名字是否可以被訪問到。通過globals()、locals()內建函式可以判斷出某一名字屬於哪個命名空間。

命名空間和作用域

1 命名空間查詢順序 假設我們要使用變數 runoob,則 python 的查詢順序為 直譯器會從命名空間中查詢runoob,它先從區域性空間查詢,如果找到了它就會使用區域性命名空間的變數runoob,即使全域性命名空間也有變數runoob。這就很容易理解為什麼在函式內部宣告的區域性變數會覆蓋掉在模...

命名空間和作用域

命名空間是對棧區的劃分,存放名字的地方.有了命名空間之後,就可以在棧區中存放相同的名字 存放的名字 存放的python直譯器內建的名字 存活週期 python直譯器啟動則產生,python直譯器關閉則銷毀 print input 存放的名字 只要不是函式內定義 也不是內建的,剩下的都是全域性命名空間...

命名空間和作用域

函式內部的函式只能在函式內部呼叫,不能在函式外部呼叫,通過接下來的學習你將會知道為什麼會出現這種情況。def f1 def f2 print from f2 f2 f2 nameerror name f2 is not defined 命名空間 name spaces 在記憶體管理那一章節時,我們曾...