python中_init_.py 到底有啥用?

北京测试菜鸟發表於2024-10-12

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']

相關文章