python常規(guī)包與命名空間包
1. 常規(guī)包
在 Python 3.3 之前或者說 Python 2 中,一個(gè)包想要被導(dǎo)入使用,那么該包內(nèi)必須要有 __init__.py
文件,這個(gè)文件是 Python 識(shí)別一個(gè)文件夾是否是一個(gè) Python 的重要標(biāo)志。
舉個(gè)例子,現(xiàn)在有如下的目錄樹,demo 及子文件夾 foo 和 bar 下都有 __init__.py
文件。
$ tree demo/
demo/
├── bar
│ └── __init__.py
├── foo
│ └── __init__.py
└── __init__.py
在該目錄下進(jìn)入 Python Console 模式,然后就可以正常導(dǎo)入了
>>> import demo
>>> import demo.bar
>>> import demo.foo
如果此時(shí)我把 demo 目錄下的 __init__.py
刪除
$ tree demo/
demo/
├── bar
│ └── __init__.py
└── foo
└── __init__.py
再導(dǎo)入就會(huì)報(bào)錯(cuò)。
>>> import demo
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named demo
2. 命名空間包
在 Python 3.3 之后(PEP 420),即使一個(gè)文件夾中沒有定義 __init__.py
,也是可以被導(dǎo)入的,只不過它不是以 Python 包的形式導(dǎo)入,而是以命名空間包 (Namespace package) 的形式被導(dǎo)入,而這一特性是在 Python 3.3 被引入的。
比如還是上面的目錄結(jié)構(gòu):
$ tree demo/
demo/
├── bar
│ └── __init__.py
└── foo
└── __init__.py
在 Python 3 下進(jìn)入 Python Console 模式,發(fā)現(xiàn)導(dǎo)入是正常的
>>> import demo
>>> import demo.foo
>>> import demo.bar
使用 __path__
查看一下,發(fā)現(xiàn) demo 不再是一個(gè)常規(guī)包了,而是一個(gè) namespace package
>>> demo
>>>
>>> demo.__path__
_NamespacePath(['/root/python/demo'])
3. 空間命名包的好處
利用命名空間包這個(gè)技術(shù),可以用來導(dǎo)入目錄分散的代碼。
比如有如下的目錄樹
$ tree
.
├── xc-pkg
│ └── demo
│ └── foo
│ └── __init__.py
└── xm-pkg
└── demo
└── bar
└── __init__.py
在這 xc-pkg
和 xm-pkg
這兩個(gè)目錄里,都有著共同的命名空間 demo。這時(shí)候再導(dǎo)入這兩個(gè)包的時(shí)候,發(fā)現(xiàn)這兩個(gè)包被合并到一起了
>>> import sys
>>> sys.path.extend(['xm-pkg', 'xc-pkg'])
>>>
>>> import demo.foo
>>> import demo.bar
>>> demo
在這里工作的機(jī)制被稱為命名空間包
的一個(gè)特征。從本質(zhì)上講,命名空間包
是一種特殊的封裝設(shè)計(jì),為合并不同的目錄的代碼到一個(gè)共同的命名空間。
命名空間包
的關(guān)鍵是確保頂級(jí)目錄中沒有 __init__.py
文件來作為共同的命名空間。缺失 __init__.py
文件使得在導(dǎo)入包的時(shí)候會(huì)發(fā)生有趣的事情:這并沒有產(chǎn)生錯(cuò)誤,解釋器創(chuàng)建了一個(gè)由所有包含匹配包名的目錄組成的列表。特殊的包命名空間模塊被創(chuàng)建,只讀的目錄列表副本被存儲(chǔ)在其 __path__
變量中。
>>> demo.__path__
_NamespacePath(['xm-pkg/demo', 'xc-pkg/demo'])
一個(gè)包是否被作為一個(gè)包命名空間的主要方法是檢查其 __file__
屬性。如果沒有,那包是個(gè)命名空間。這也可以由其字符表現(xiàn)形式中的 namespace 這個(gè)詞體現(xiàn)出來。
>>> demo
>>>
>>> demo.__file__
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'demo' has no attribute '__file__'
審核編輯:湯梓紅
-
結(jié)構(gòu)
+關(guān)注
關(guān)注
1文章
117瀏覽量
21908 -
空間
+關(guān)注
關(guān)注
2文章
50瀏覽量
13826 -
python
+關(guān)注
關(guān)注
56文章
4825瀏覽量
86255
發(fā)布評(píng)論請(qǐng)先 登錄
藍(lán)牙數(shù)據(jù)通道空口包(數(shù)據(jù)包)
藍(lán)牙廣播包
Bluetooth LE Link Layer數(shù)據(jù)包全解析
移動(dòng)電源鼓包怎么回事及處理方法
I2C總線數(shù)據(jù)包結(jié)構(gòu)詳解
華納云如何解讀WinMTR的丟包率數(shù)據(jù)?
mtu配置步驟詳解 mtu與數(shù)據(jù)包丟失的關(guān)系
Linux網(wǎng)卡收包流程

什么是膜包壓方線?

使用Python進(jìn)行Ping測(cè)試

經(jīng)典藍(lán)牙抓包解析說明

評(píng)論