攝影:產品經理
有了它,樂高已經不香了
Python 初學者在閱讀一些 Python 開源項目時,經常會看到一個叫作init.py的文件。下圖爲著名的第三方庫requests的源代碼:ide
那麼init.py有什麼用呢?本文介紹它的兩個用途。函數
精簡導入路徑code
假設咱們有兩個文件main.py與writer.py,他們所在的文件結構以下圖所示:
blog
main.py在DocParser文件夾下面;writer.py在DocParser/microsoft/docx/文件夾下面。writer.py文件中有一個函數write。其內容以下:
requests
如今我想在main.py文件夾調用這個函數,那麼我有3種寫法:產品
from microsoft.word.docx.writer import write write()
運行效果以下圖所示:
it
或者這樣寫:class
from microsoft.word.docx import writer writer.write()
運行效果以下圖所示:
import
或者這樣寫:bfc
import microsoft.word.docx.writer microsoft.word.docx.writer.write()
運行效果以下圖所示:
但不管那種方法,都要寫長長的路徑,甚爲不便。這個時候,咱們能夠在microsoft文件夾下面建立一個init.py文件,並在裏面填寫以下內容:
此時,在 main.py,咱們導入write函數,就像是從microsoft.py 文件中導入同樣。以下圖所示:
注意上面我說的是就像從microsoft.py 文件中導入同樣,這裏是用的文件而不是文件夾。
這是由於,當一個文件夾裏面有init.py之後,這個文件夾就會被 Python 做爲一個包(package)來處理。此時,對於這個包裏面層級比較深的函數、常量、類,咱們能夠先把它們導入到init.py中。這樣以來,包外面再想導入這些內容時,就能夠用from 包名 import 函數名來導入了。
無視工做區的相對引用
爲何會有包這個東西呢?這是由於,當有一些代碼會在不少地方被使用時,咱們能夠把這些代碼打包起來,做爲一個公共的部分提供給其餘模塊調用。
因爲調用包的其餘模塊所在的絕對路徑是變幻無窮的,因此在包的內部調用自身其餘文件中的函數、常量、類,就應該使用相對路徑,而不是絕對路徑。
例如,如今我在microsoft文件夾下面再建立一個parse.py文件,它須要導入microsoft/word/docx/writer.py中的write函數,那麼代碼能夠寫爲:
from .word.docx.writer import write def parse_doc(): print('如今在 parse.py 中調用 write 函數') write()
以下圖所示:
能夠看到,此時from .word.docx.writer中的.表示當前包,因此.word.docx.writer表示當前包下面的word 文件夾下面的 docx 文件夾下面的 writer.py 文件。
而後咱們修改init.py,把parse_doc函數導入進去,以下圖所示:
最後,在main.py中調用這個parse_doc函數,以下圖所示:
能夠看到,在包裏面的一個文件調用這個包裏面的另外一個文件,只須要知道另外一個文件的相對位置就能夠了,不用關心這個包被放在哪裏。
而且,上面parse.py中導入write函數的代碼還能夠進一步簡化,因爲write函數已經被導入到了init.py中,因此咱們能夠直接從.裏面導入write函數:
from . import write
運行效果以下圖所示:
總結
當一個文件夾裏面包含init.py時,這個文件夾會被 Python 認爲是一個包(package),此時,包內部的文件之間互相導入可使用相對導入,而且經過提早把函數、常量、類導入到init.py中再在其餘文件中導入,能夠精簡代碼。