python __init__.py 的學(xué)習(xí)(轉(zhuǎn))

Python雜談: init.py的作用

我們經(jīng)常在python的模塊目錄中會看到 "init.py" 這個文件,那么它到底有什么作用呢逐工?

1. 標(biāo)識該目錄是一個python的模塊包(module package)

如果你是使用python的相關(guān)IDE來進(jìn)行開發(fā)嫉戚,那么如果目錄中存在該文件对嚼,該目錄就會被識別為 module package 机蔗。

2. 簡化模塊導(dǎo)入操作

假設(shè)我們的模塊包的目錄結(jié)構(gòu)如下:

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">.
└── mypackage
├── subpackage_1
│ ├── test11.py
│ └── test12.py
├── subpackage_2
│ ├── test21.py
│ └── test22.py
└── subpackage_3
├── test31.py
└── test32.py</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

如果我們使用最直接的導(dǎo)入方式背传,將整個文件拷貝到工程目錄下剩盒,然后直接導(dǎo)入:

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">from mypackage.subpackage_1 import test11 from mypackage.subpackage_1 import test12 from mypackage.subpackage_2 import test21 from mypackage.subpackage_2 import test22 from mypackage.subpackage_3 import test31 from mypackage.subpackage_3 import test32</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

當(dāng)然這個例子里面文件比較少谷婆,如果模塊比較大,目錄比較深的話辽聊,可能自己都記不清該如何導(dǎo)入纪挎。(很有可能,哪怕只想導(dǎo)入一個模塊都要在目錄中找很久)

這種情況下跟匆,init.py 就很有作用了异袄。我們先來看看該文件是如何工作的。

2.1 init.py 是怎么工作的玛臂?

實際上烤蜕,如果目錄中包含了 init.py 時,當(dāng)用 import 導(dǎo)入該目錄時迹冤,會執(zhí)行 init.py 里面的代碼讽营。

我們在mypackage目錄下增加一個 init.py 文件來做一個實驗:

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">.
└── mypackage
├── init.py
├── subpackage_1
│ ├── test11.py
│ └── test12.py
├── subpackage_2
│ ├── test21.py
│ └── test22.py
└── subpackage_3
├── test31.py
└── test32.py</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

mypackage/init.py 里面加一個print,如果執(zhí)行了該文件就會輸出:

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">print("You have imported mypackage")</pre>

下面直接用交互模式進(jìn)行 import

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">>>> import mypackage
You have imported mypackage</pre>

很顯然叁巨,init.py 在包被導(dǎo)入時會被執(zhí)行斑匪。

2.2 控制模塊導(dǎo)入

我們再做一個實驗,在 mypackage/init.py 添加以下語句:

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">from subpackage_1 import test11</pre>

我們導(dǎo)入 mypackage 試試:

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">>>> import mypackage
Traceback (most recent call last):
File "<stdin>", line 1, in <module> File "/home/taopeng/Workspace/Test/mypackage/init.py", line 2, in <module>
from subpackage_1 import test11
ImportError: No module named 'subpackage_1'</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

報錯了。蚀瘸。狡蝶。怎么回事?

原來贮勃,在我們執(zhí)行import時贪惹,當(dāng)前目錄是不會變的(就算是執(zhí)行子目錄的文件),還是需要完整的包名寂嘉。

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">from mypackage.subpackage_1 import test11</pre>

綜上奏瞬,我們可以在init.py 指定默認(rèn)需要導(dǎo)入的模塊

2.3 偷懶的導(dǎo)入方法

有時候我們在做導(dǎo)入時會偷懶,將包中的所有內(nèi)容導(dǎo)入

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">from mypackage import *</pre>

這是怎么實現(xiàn)的呢泉孩? **all **變量就是干這個工作的硼端。

all 關(guān)聯(lián)了一個模塊列表,當(dāng)執(zhí)行** from xx import * **時寓搬,就會導(dǎo)入列表中的模塊珍昨。我們將 init.py 修改為 。

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">all = ['subpackage_1', 'subpackage_2']</pre>

這里沒有包含 subpackage_3句喷,是為了證明 **all **起作用了镣典,而不是導(dǎo)入了所有子目錄。

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">>>> from mypackage import *

dir()
['builtins', 'doc', 'loader', 'name', 'package', 'spec', 'subpackage_1', 'subpackage_2'] >>>
dir(subpackage_1)
['doc', 'loader', 'name', 'package', 'path', 'spec']</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

子目錄的中的模塊沒有導(dǎo)入M偾怼P执骸!

該例子中的導(dǎo)入等價于

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">from mypackage import subpackage_1, subpackage_2</pre>

因此锡溯,導(dǎo)入操作會繼續(xù)查找 subpackage_1 和 subpackage_2 中的 init.py 并執(zhí)行赶舆。(但是此時不會執(zhí)行** import ***)

我們在 subpackage_1 下添加 init.py 文件:

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">all = ['test11', 'test12'] # 默認(rèn)只導(dǎo)入test11
from mypackage.subpackage_1 import test11</pre>

再來導(dǎo)入試試

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">>>> from mypackage import *

dir()
['builtins', 'doc', 'loader', 'name', 'package', 'spec', 'subpackage_1', 'subpackage_2'] >>>
dir(subpackage_1)
['all', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'path', 'spec', 'test11']</pre>

[
復(fù)制代碼

](javascript:void(0); "復(fù)制代碼")

如果想要導(dǎo)入子包的所有模塊,則需要更精確指定趾唱。

<pre style="margin: 0px; padding: 0px; white-space: pre-wrap; overflow-wrap: break-word; font-family: "Courier New" !important; font-size: 12px !important;">>>> from mypackage.subpackage_1 import *

dir()
['builtins', 'doc', 'loader', 'name', 'package', 'spec', 'test11', 'test12']</pre>

3. 配置模塊的初始化操作

在了解了 init.py 的工作原理后涌乳,應(yīng)該能理解該文件就是一個正常的python代碼文件。

因此可以將初始化代碼放入該文件中甜癞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夕晓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子悠咱,更是在濱河造成了極大的恐慌蒸辆,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件析既,死亡現(xiàn)場離奇詭異躬贡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)眼坏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評論 2 385
  • 文/潘曉璐 我一進(jìn)店門拂玻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事檐蚜∑嵌” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評論 0 347
  • 文/不壞的土叔 我叫張陵闯第,是天一觀的道長市栗。 經(jīng)常有香客問我,道長咳短,這世上最難降的妖魔是什么填帽? 我笑而不...
    開封第一講書人閱讀 56,427評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮咙好,結(jié)果婚禮上篡腌,老公的妹妹穿的比我還像新娘。我一直安慰自己勾效,他們只是感情好哀蘑,可當(dāng)我...
    茶點故事閱讀 65,467評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葵第,像睡著了一般。 火紅的嫁衣襯著肌膚如雪合溺。 梳的紋絲不亂的頭發(fā)上卒密,一...
    開封第一講書人閱讀 49,785評論 1 290
  • 那天,我揣著相機(jī)與錄音棠赛,去河邊找鬼哮奇。 笑死,一個胖子當(dāng)著我的面吹牛睛约,可吹牛的內(nèi)容都是我干的鼎俘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼辩涝,長吁一口氣:“原來是場噩夢啊……” “哼贸伐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怔揩,我...
    開封第一講書人閱讀 37,696評論 0 266
  • 序言:老撾萬榮一對情侶失蹤捉邢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后商膊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伏伐,經(jīng)...
    沈念sama閱讀 44,141評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,483評論 2 327
  • 正文 我和宋清朗相戀三年晕拆,在試婚紗的時候發(fā)現(xiàn)自己被綠了藐翎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,625評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吝镣,靈堂內(nèi)的尸體忽然破棺而出堤器,到底是詐尸還是另有隱情,我是刑警寧澤赤惊,帶...
    沈念sama閱讀 34,291評論 4 329
  • 正文 年R本政府宣布吼旧,位于F島的核電站,受9級特大地震影響未舟,放射性物質(zhì)發(fā)生泄漏圈暗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,892評論 3 312
  • 文/蒙蒙 一裕膀、第九天 我趴在偏房一處隱蔽的房頂上張望员串。 院中可真熱鬧,春花似錦昼扛、人聲如沸寸齐。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽渺鹦。三九已至,卻和暖如春蛹含,著一層夾襖步出監(jiān)牢的瞬間毅厚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工浦箱, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留吸耿,地道東北人。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓酷窥,卻偏偏與公主長得像咽安,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蓬推,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,492評論 2 348