python常規(guī)包與命名空間包
1. 常規(guī)包
在 Python 3.3 之前或者說 Python 2 中,一個包想要被導入使用,那么該包內(nèi)必須要有 __init__.py
文件,這個文件是 Python 識別一個文件夾是否是一個 Python 的重要標志。
舉個例子,現(xiàn)在有如下的目錄樹,demo 及子文件夾 foo 和 bar 下都有 __init__.py
文件。
$ tree demo/
demo/
├── bar
│ └── __init__.py
├── foo
│ └── __init__.py
└── __init__.py
在該目錄下進入 Python Console 模式,然后就可以正常導入了
>>> import demo
>>> import demo.bar
>>> import demo.foo
如果此時我把 demo 目錄下的 __init__.py
刪除
$ tree demo/
demo/
├── bar
│ └── __init__.py
└── foo
└── __init__.py
再導入就會報錯。
>>> import demo
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named demo
2. 命名空間包
在 Python 3.3 之后(PEP 420),即使一個文件夾中沒有定義 __init__.py
,也是可以被導入的,只不過它不是以 Python 包的形式導入,而是以命名空間包 (Namespace package) 的形式被導入,而這一特性是在 Python 3.3 被引入的。
比如還是上面的目錄結(jié)構(gòu):
$ tree demo/
demo/
├── bar
│ └── __init__.py
└── foo
└── __init__.py
在 Python 3 下進入 Python Console 模式,發(fā)現(xiàn)導入是正常的
>>> import demo
>>> import demo.foo
>>> import demo.bar
使用 __path__
查看一下,發(fā)現(xiàn) demo 不再是一個常規(guī)包了,而是一個 namespace package
>>> demo
>>>
>>> demo.__path__
_NamespacePath(['/root/python/demo'])
3. 空間命名包的好處
利用命名空間包這個技術,可以用來導入目錄分散的代碼。
比如有如下的目錄樹
$ tree
.
├── xc-pkg
│ └── demo
│ └── foo
│ └── __init__.py
└── xm-pkg
└── demo
└── bar
└── __init__.py
在這 xc-pkg
和 xm-pkg
這兩個目錄里,都有著共同的命名空間 demo。這時候再導入這兩個包的時候,發(fā)現(xiàn)這兩個包被合并到一起了
>>> import sys
>>> sys.path.extend(['xm-pkg', 'xc-pkg'])
>>>
>>> import demo.foo
>>> import demo.bar
>>> demo
在這里工作的機制被稱為命名空間包
的一個特征。從本質(zhì)上講,命名空間包
是一種特殊的封裝設計,為合并不同的目錄的代碼到一個共同的命名空間。
命名空間包
的關鍵是確保頂級目錄中沒有 __init__.py
文件來作為共同的命名空間。缺失 __init__.py
文件使得在導入包的時候會發(fā)生有趣的事情:這并沒有產(chǎn)生錯誤,解釋器創(chuàng)建了一個由所有包含匹配包名的目錄組成的列表。特殊的包命名空間模塊被創(chuàng)建,只讀的目錄列表副本被存儲在其 __path__
變量中。
>>> demo.__path__
_NamespacePath(['xm-pkg/demo', 'xc-pkg/demo'])
一個包是否被作為一個包命名空間的主要方法是檢查其 __file__
屬性。如果沒有,那包是個命名空間。這也可以由其字符表現(xiàn)形式中的 namespace 這個詞體現(xiàn)出來。
>>> demo
>>>
>>> demo.__file__
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'demo' has no attribute '__file__'
審核編輯:湯梓紅
-
結(jié)構(gòu)
+關注
關注
1文章
117瀏覽量
21613 -
空間
+關注
關注
2文章
48瀏覽量
13659 -
python
+關注
關注
56文章
4800瀏覽量
84820
發(fā)布評論請先 登錄
相關推薦
評論