W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
你可能有大量的代碼,由不同的人來分散地維護(hù)。每個(gè)部分被組織為文件目錄,如一個(gè)包。然而,你希望能用共同的包前綴將所有組件連接起來,不是將每一個(gè)部分作為獨(dú)立的包來安裝。
從本質(zhì)上講,你要定義一個(gè)頂級Python包,作為一個(gè)大集合分開維護(hù)子包的命名空間。這個(gè)問題經(jīng)常出現(xiàn)在大的應(yīng)用框架中,框架開發(fā)者希望鼓勵用戶發(fā)布插件或附加包。
在統(tǒng)一不同的目錄里統(tǒng)一相同的命名空間,但是要刪去用來將組件聯(lián)合起來的init.py文件。假設(shè)你有Python代碼的兩個(gè)不同的目錄如下:
foo-package/
spam/
blah.py
bar-package/
spam/
grok.py
在這2個(gè)目錄里,都有著共同的命名空間spam。在任何一個(gè)目錄里都沒有init.py文件。
讓我們看看,如果將foo-package和bar-package都加到python模塊路徑并嘗試導(dǎo)入會發(fā)生什么
>>> import sys
>>> sys.path.extend(['foo-package', 'bar-package'])
>>> import spam.blah
>>> import spam.grok
>>>
兩個(gè)不同的包目錄被合并到一起,你可以導(dǎo)入spam.blah和spam.grok,并且它們能夠工作。
在這里工作的機(jī)制被稱為“包命名空間”的一個(gè)特征。從本質(zhì)上講,包命名空間是一種特殊的封裝設(shè)計(jì),為合并不同的目錄的代碼到一個(gè)共同的命名空間。對于大的框架,這可能是有用的,因?yàn)樗试S一個(gè)框架的部分被單獨(dú)地安裝下載。它也使人們能夠輕松地為這樣的框架編寫第三方附加組件和其他擴(kuò)展。
包命名空間的關(guān)鍵是確保頂級目錄中沒有init.py文件來作為共同的命名空間。缺失init.py文件使得在導(dǎo)入包的時(shí)候會發(fā)生有趣的事情:這并沒有產(chǎn)生錯誤,解釋器創(chuàng)建了一個(gè)由所有包含匹配包名的目錄組成的列表。特殊的包命名空間模塊被創(chuàng)建,只讀的目錄列表副本被存儲在其path變量中。 舉個(gè)例子:
>>> import spam
>>> spam.__path__
_NamespacePath(['foo-package/spam', 'bar-package/spam'])
>>>
在定位包的子組件時(shí),目錄path將被用到(例如, 當(dāng)導(dǎo)入spam.grok或者spam.blah的時(shí)候).
包命名空間的一個(gè)重要特點(diǎn)是任何人都可以用自己的代碼來擴(kuò)展命名空間。舉個(gè)例子,假設(shè)你自己的代碼目錄像這樣:
my-package/
spam/
custom.py
如果你將你的代碼目錄和其他包一起添加到sys.path,這將無縫地合并到別的spam包目錄中:
>>> import spam.custom
>>> import spam.grok
>>> import spam.blah
>>>
一個(gè)包是否被作為一個(gè)包命名空間的主要方法是檢查其file屬性。如果沒有,那包是個(gè)命名空間。這也可以由其字符表現(xiàn)形式中的“namespace”這個(gè)詞體現(xiàn)出來。
>>> spam.__file__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'
>>> spam
<module 'spam' (namespace)>
>>>
更多的包命名空間信息可以查看?PEP 420.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: