你常常看到卻常常忽視的__init__.py有什麼用?

你常常看到卻常常忽視的init.py有什麼用?

你常常看到卻常常忽視的__init__.py有什麼用?

攝影:產品經理
有了它,樂高已經不香了
Python 初學者在閱讀一些 Python 開源項目時,經常會看到一個叫作init.py的文件。下圖爲著名的第三方庫requests的源代碼:ide

你常常看到卻常常忽視的__init__.py有什麼用?
那麼init.py有什麼用呢?本文介紹它的兩個用途。函數

精簡導入路徑code

假設咱們有兩個文件main.py與writer.py,他們所在的文件結構以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?blog

main.py在DocParser文件夾下面;writer.py在DocParser/microsoft/docx/文件夾下面。writer.py文件中有一個函數write。其內容以下:
你常常看到卻常常忽視的__init__.py有什麼用?requests

如今我想在main.py文件夾調用這個函數,那麼我有3種寫法:產品

from microsoft.word.docx.writer import write

write()

運行效果以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?it

或者這樣寫:class

from microsoft.word.docx import writer

writer.write()

運行效果以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?import

或者這樣寫:bfc

import microsoft.word.docx.writer

microsoft.word.docx.writer.write()

運行效果以下圖所示:

你常常看到卻常常忽視的__init__.py有什麼用?
但不管那種方法,都要寫長長的路徑,甚爲不便。這個時候,咱們能夠在microsoft文件夾下面建立一個init.py文件,並在裏面填寫以下內容:
你常常看到卻常常忽視的__init__.py有什麼用?

此時,在 main.py,咱們導入write函數,就像是從microsoft.py 文件中導入同樣。以下圖所示:
你常常看到卻常常忽視的__init__.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()

以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?

能夠看到,此時from .word.docx.writer中的.表示當前包,因此.word.docx.writer表示當前包下面的word 文件夾下面的 docx 文件夾下面的 writer.py 文件。

而後咱們修改init.py,把parse_doc函數導入進去,以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?

最後,在main.py中調用這個parse_doc函數,以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?

能夠看到,在包裏面的一個文件調用這個包裏面的另外一個文件,只須要知道另外一個文件的相對位置就能夠了,不用關心這個包被放在哪裏。

而且,上面parse.py中導入write函數的代碼還能夠進一步簡化,因爲write函數已經被導入到了init.py中,因此咱們能夠直接從.裏面導入write函數:

from . import write

運行效果以下圖所示:
你常常看到卻常常忽視的__init__.py有什麼用?

總結

當一個文件夾裏面包含init.py時,這個文件夾會被 Python 認爲是一個包(package),此時,包內部的文件之間互相導入可使用相對導入,而且經過提早把函數、常量、類導入到init.py中再在其餘文件中導入,能夠精簡代碼。
你常常看到卻常常忽視的__init__.py有什麼用?

相關文章
相關標籤/搜索