__init__.py的相關(guān)解釋

參考鏈接:http://blog.csdn.net/zyl1042635242/article/details/44196601

? Python中常見(jiàn)的文件導(dǎo)入模式:事先寫(xiě)好一個(gè).py文件,如果在另一個(gè).py文件中需要導(dǎo)入事先寫(xiě)好的.py文件時(shí),就將事先寫(xiě)好的.py文件拷貝到當(dāng)前目錄,或者是sys.path增加事先寫(xiě)好的.py文件所在的目錄,然后import。這種做法對(duì)于少數(shù)文件是可行的,但如果程序數(shù)目多,層級(jí)復(fù)雜,就不適用。鑒于此,我們希望找到一種辦法,像Java的Package一樣,能將多個(gè).py文件組織起來(lái),以實(shí)現(xiàn)在外部統(tǒng)一調(diào)用和在內(nèi)部互相調(diào)用。

其實(shí),主要是用到Python的包的概念,而__init__.py在包里起著重要作用。要弄明白這個(gè)問(wèn)題,首先要知道,Python在執(zhí)行import語(yǔ)句時(shí),到底進(jìn)行了什么操作,按照python的文檔,它執(zhí)行了如下操作:

第1步,創(chuàng)建一個(gè)新的,空的module對(duì)象(它可能包含多個(gè)module)

第2步,把這個(gè)module對(duì)象插入sys.module中

第3步,裝載module的代碼(如果需要,首先必須編譯)

第4步,執(zhí)行新的module中對(duì)應(yīng)的代碼。

在執(zhí)行第3步時(shí),首先要找到module程序所在的位置。其原理為:如果需要導(dǎo)入的module的名字是m1,則解釋器必須找到m1.py,它首先在當(dāng)前目錄查找,然后是在環(huán)境變量PYTHONPATH中查找。PYTHONPATH可以視為系統(tǒng)的PATH變量一類(lèi)的東西,其中包含若干個(gè)目錄。如果PYTHONPATH沒(méi)有設(shè)定,或者找不到m1.py,則繼續(xù)搜索與Python的安裝設(shè)置相關(guān)的默認(rèn)路徑。正因?yàn)榇嬖谶@樣的順序,如果當(dāng)前路徑或PYTHONPATH中存在與標(biāo)準(zhǔn)module同樣的module,則會(huì)覆蓋標(biāo)準(zhǔn)module。也就是說(shuō),如果當(dāng)前目錄下存在xml.py,那么執(zhí)行import xml時(shí),導(dǎo)入的是當(dāng)前目錄下的module,而不是系統(tǒng)標(biāo)準(zhǔn)的xml。

了解了這些,我們就可以先構(gòu)建一個(gè)package,以普通module的方式導(dǎo)入,就可以直接訪問(wèn)此package中的各個(gè)module了。Python中的package定義很簡(jiǎn)單,其層次結(jié)構(gòu)與程序所在目錄的層次結(jié)構(gòu)相同,這一點(diǎn)與Java類(lèi)似,唯一不同的地方在于,python中的package必須包含一個(gè)__init__.py的文件。

例如,我們可以這樣組織一個(gè)package:

package1/

??? __init__.py

??? subPack1/

??? ??? __init__.py

??? ??? module_11.py

??? ??? module_12.py

??? ??? module_13.py

??? subPack2/

??? ??? __init__.py

??? ??? module_21.py

??? ??? module_22.py

……

__init__.py可以為空,只要它存在,就表明此目錄應(yīng)被作為一個(gè)package處理。當(dāng)然,__init__.py中也可以設(shè)置相應(yīng)的內(nèi)容,下文詳細(xì)介紹。好了,現(xiàn)在我們?cè)趍odule_11.py中定義一個(gè)函數(shù):

def funA():

??? print "funcA in module_11"

??? return

在頂層目錄(也就是package1所在的目錄,當(dāng)然也參考上面的介紹,將package1放在解釋器能夠搜索到的地方)運(yùn)行python:

>>>from package1.subPack1.module_11 import funcA

>>>funcA()

funcA in module_11

這樣,我們就按照package的層次關(guān)系,正確調(diào)用了module_11中的函數(shù)。

細(xì)心的用戶(hù)會(huì)發(fā)現(xiàn),有時(shí)在import語(yǔ)句中會(huì)出現(xiàn)通配符*,導(dǎo)入某個(gè)module中的所有元素,這是怎么實(shí)現(xiàn)的呢?

答案就在__init__.py中。我們?cè)趕ubPack1的__init__.py文件中寫(xiě)

__all__ = ['module_13', 'module_12'] ,然后進(jìn)入python

>>>from package1.subPack1 import *

>>>module_11.funcA()

Traceback (most recent call last):

? File "", line 1, in ImportError: No module named module_11

也就是說(shuō),以*導(dǎo)入時(shí),package內(nèi)的module是受__init__.py限制的。

好了,最后來(lái)看看,如何在package內(nèi)部互相調(diào)用。如果希望調(diào)用同一個(gè)package中的module,則直接import即可。也就是說(shuō),在module_12.py中,可以直接使用

import module_11

如果不在同一個(gè)package中,例如我們希望在module_21.py中調(diào)用module_11.py中的FuncA,則應(yīng)該這樣:

from module_11包名.module_11 import funcA

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容