1. __init__.py 是個啥?
__init__.py,這個檔名就是用來“初始化”的。在Python裡,它主要用於標識一個目錄是一個“包(Package)”。在專案裡新建了一個資料夾,要讓它成為一個可供匯入的模組包,最簡單的辦法就是在裡面加一個__init__.py。
比如,咱們有個專案結構如下:
my_project/ ├── __init__.py ├── module1.py └── module2.py
想要在外部使用 my_projec t這個包時,就可以這樣匯入:
import my_project
有了__init__.py的存在,Python才知道my_project是一個包,而不是一個普通的資料夾。所以這個檔案的基本作用就是:告訴Python,“這裡是個包,可以在其他地方匯入我!”
2. __init__.py 還能做些啥?
1. 模組初始化操作
假如有一個需要初始化配置的工具包,可以在__init__.py裡直接搞定這些初始化工作。
# 例子:my_project/__init__.py import os # 初始化配置檔案路徑 config_file = os.path.join(os.path.dirname(__file__), 'config.yaml') print("正在初始化配置檔案……")
當一匯入my_project時,config.yaml就被自動載入了。再也不用在每個子模組裡重複配置路徑!
2.控制子模組匯入
透過在__init__.py中匯入函式,可以直接在 import package_name 的時候就將所有常用的子模組或者函式匯入,這樣就能從包的頂級目錄直接訪問子模組的內容了:
3.包級別變數和函式的初始化
還可以在__init__.py裡設定一些全域性變數,或者定義一些包級別的工具函式。
3. __init__.py 的一些“坑”【迴圈匯入】
什麼是迴圈匯入?
假設有兩個模組module1和module2,然後在module1.py中寫了這樣一段程式碼:
# module1.py from .module2 import some_function
然後又在module2.py裡這樣寫
# module2.py from .module1 import another_function
這就會導致Python在匯入包的時候出現死迴圈,結果是兩邊互相等待對方載入,最終就會報錯或者無法正常匯入。
4. __init__.py 和相對匯入的關係
相對匯入和絕對匯入
__init__.py裡用相對匯入的語法,比如:
from .module1 import func1
看上去沒問題,但等到跑module1.py這個檔案時,就會發現報錯了!因為相對匯入的方式要求你必須從頂層包開始匯入。而你直接執行module1.py,Python根本不知道它是從哪個包裡來的。
建議儘量使用絕對匯入,比如這樣:
from my_project.module1 import func1
這樣不管是直接執行module1.py,還是匯入整個my_project,都不會有問題。
5. 還有哪些小技巧?
避免複雜邏輯:不要在__init__.py中寫太複雜的業務邏輯。應該是輕量級的初始化和匯入,不然以後維護起來會非常麻煩。
模組匯出控制:你可以用__all__來控制從包中匯出哪些模組或變數。
這樣當你用 from my_project import *時,Python只會匯入__all__指定的內容
__all__ = ['module1', 'module2']