欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文帶你搞懂Python中__init__.py到底是什么

 更新時間:2025年04月22日 16:06:49   作者:花小姐的春天  
朋友們,今天我們來聊聊 Python 里一個低調(diào)卻至關(guān)重要的文件——__init__.py,有些人可能聽說過它是“包的標(biāo)志”,也有人覺得它“沒啥大用,可以忽略”,今天我們就來徹底搞清楚 __init__.py 到底是干啥的

朋友們,今天我們來聊聊 Python 里一個低調(diào)卻至關(guān)重要的文件——__init__.py。

說實話,這玩意兒剛開始學(xué) Python 時,很多人(包括當(dāng)年的我)都是一臉懵:“這啥?刪了會咋樣?”

有些人可能聽說過它是“包的標(biāo)志”,也有人覺得它“沒啥大用,可以忽略”,更有甚者以為它“只是個裝樣子的文件”。今天,我們就來徹底搞清楚 __init__.py 到底是干啥的,以及它如何影響 Python 項目的結(jié)構(gòu)和運行。

先搞懂 Python 模塊(module)

在聊 __init__.py 之前,我們得先弄清楚 Python 里的 模塊 這兩個概念。

模塊(module):簡單來說,就是一個 .py 文件,里面寫了一些函數(shù)、類或者變量。

比如,有個叫 math_tools.py 的文件,里面有一堆數(shù)學(xué)工具函數(shù),那它就是個模塊。

# math_tools.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

然后,我們可以在別的 Python 文件里這樣用它:

import math_tools

print(math_tools.add(3, 5))  # 輸出 8

這就是 模塊的基本用法,沒啥難的,對吧?

Python 包(package)是啥?

如果你寫的模塊越來越多,代碼量越來越大,就得想辦法組織它們。這時候,Python 里的 包(package) 就派上用場了。

包(package):一個 文件夾,里面包含多個模塊(.py 文件)。

Python 3.3 之前,如果要讓一個目錄被識別為 Python 包,必須在里面創(chuàng)建 __init__.py 文件。但從 Python 3.3 開始,即使沒有 __init__.py,Python 也能識別它是一個包(稱為“命名空間包”)。

不過,大部分實際項目 依然建議添加 __init__.py,因為它可以:

? 明確這個文件夾是一個包,避免某些工具(如打包工具)識別錯誤。

? 允許在包初始化時執(zhí)行特定代碼,比如自動導(dǎo)入子模塊。

? 讓導(dǎo)入行為更加可控,避免意外的命名沖突。

比如,咱們有個 math_utils 目錄,里面放了幾個數(shù)學(xué)相關(guān)的模塊:

math_utils/     # 這個文件夾就是一個包
│── __init__.py
│── basic.py
│── advanced.py

其中,basic.pyadvanced.py 分別是兩個模塊,而 __init__.py 可以用來 自定義包的導(dǎo)入行為。

那么 __init__.py 到底是干嘛的?

雖然 __init__.py 不再是創(chuàng)建包的 必需 條件,但它依然是 Python 項目里一個重要的組件。

它的主要作用有 兩個

1.明確標(biāo)記目錄為 Python 包

如果 __init__.py 存在,Python 解析器就會知道:“這個目錄是個 Python 包,而不是普通文件夾。”

即使 Python 3.3+ 之后不強制要求 __init__.py,但加上它可以:

? 避免 Python 解釋器在某些情況下誤認(rèn)為這是普通目錄。

? 兼容舊版本 Python,讓代碼能在不同環(huán)境中運行得更穩(wěn)定。

? 讓某些工具(如 pytest、mypy)更好地識別項目結(jié)構(gòu)。

2.讓包能像模塊一樣被導(dǎo)入

如果 __init__.py 里什么都不寫,那它的作用只是個“標(biāo)志”。但如果我們在 __init__.py 里加點代碼,它就能 自定義包的導(dǎo)入行為。

示例 1:讓包直接暴露子模塊

# math_utils/__init__.py
from .basic import add, subtract
from .advanced import power

這樣,我們就可以直接 import 整個 math_utils,而不需要寫 .basic.advanced 了:

import math_utils

print(math_utils.add(2, 3))  # 輸出 5
print(math_utils.power(2, 3))  # 假設(shè) advanced 里有個 power 函數(shù)

等于說,__init__.py包變得像一個大模塊 一樣,外部不需要知道里面的模塊結(jié)構(gòu),直接用就行。

示例 2:包初始化操作

__init__.py 還能在包被導(dǎo)入時執(zhí)行一些初始化操作,比如加載配置、設(shè)置日志等:

# math_utils/__init__.py
print("數(shù)學(xué)工具包加載成功!")  # 只要 import 這個包,就會執(zhí)行這行代碼

__init__.py 還能干點啥

大廠的 Python 項目里,__init__.py 還經(jīng)常被用來做這些事:

1. 動態(tài)導(dǎo)入子模塊

在大型 Python 項目中,隨著模塊越來越多,手動維護__init__.py將變得特別復(fù)雜還容易出錯,這時候動態(tài)導(dǎo)入子模塊就成了香餑餑了。
假設(shè)我們不知道 math_utils 里具體有哪些模塊,可以讓 __init__.py 在導(dǎo)入時動態(tài)掃描并加載:

# math_utils/__init__.py
import os
import importlib

# 獲取當(dāng)前包的路徑
package_path = os.path.dirname(__file__)

# 遍歷當(dāng)前目錄下的所有 .py 文件(不包括 __init__.py 本身)
for module in os.listdir(package_path):
    if module.endswith(".py") and module != "__init__.py":
        module_name = module[:-3]  # 去掉 .py 后綴
        importlib.import_module(f"{__name__}.{module_name}")  # 動態(tài)導(dǎo)入模塊

效果: 這樣,當(dāng)你在別的地方寫 import mypackage,所有 mypackage 里的 .py 文件都會自動加載,不用再手動 import 了!

沒加動態(tài)導(dǎo)入要這么寫:

import math_utils.basic
print(math_utils.basic.add(1,2))

#如果直接 import math_utils 會報錯AttributeError: module 'math_utils' has no attribute 'basic'

加了動態(tài)導(dǎo)入可以這么寫:

import math_utils
print(math_utils.basic.add(1,2))

2. 控制對外暴露的模塊

有時候,我們不想讓 所有 子模塊都被自動導(dǎo)入,而是只暴露一部分給外部用。這時候可以用 __all__手動控制 允許被 from mypackage import * 訪問的模塊。

# math_utils/__init__.py
import os
import importlib

package_path = os.path.dirname(__file__)
__all__ = []

for module in os.listdir(package_path):
    if module.endswith(".py") and module != "__init__.py":
        module_name = module[:-3]
        __all__.append(module_name)  # 只暴露在 __all__ 里的模塊
        importlib.import_module(f"{__name__}.{module_name}")

效果

from math_utils import *

print(basic)  # 只有在 __all__ 里的模塊能被導(dǎo)入 

3. 懶加載(Lazy Import)

如果某些模塊比較大,加載它們會影響性能,那可以用 懶加載(lazy import)技術(shù),在需要時才導(dǎo)入,而不是在 import mypackage 時一次性全加載。

# math_utils/__init__.py
import importlib

def lazy_import(name):
    return importlib.import_module(f"{__name__}.{name}")

module1 = lazy_import("basic")

效果

這樣,basic 只有在第一次被使用時才會真正導(dǎo)入,提高了性能!

4. 做版本控制

__init__.py 還能給包加上版本號,讓外部代碼可以訪問:

# math_utils/__init__.py
__version__ = "1.0.0"

然后,在別的地方可以這樣用:

import math_utils

print(math_utils.__version__)  # 輸出 "1.0.0"

5. 隱藏內(nèi)部實現(xiàn)

有些模塊是“內(nèi)部用”的,不想讓外部訪問,怎么辦?可以在 __init__.py 里手動控制 對外暴露的內(nèi)容

# math_utils/__init__.py
from .basic import add, subtract

__all__ = ["add", "subtract"]  # advanced.py 里的東西就不會被直接 import

這樣,外部只能用 math_utils.add(),但 math_utils.advanced 就不讓直接訪問了。

結(jié)尾

關(guān)于 __init__.py,咱們就聊到這兒!希望這篇文章能幫你徹底搞懂它的作用,今后寫 Python 項目時能更自信地使用它。

到此這篇關(guān)于一文帶你搞懂Python中__init__.py到底是什么的文章就介紹到這了,更多相關(guān)Python __init__.py內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python異步的ASGI與Fast Api實現(xiàn)

    python異步的ASGI與Fast Api實現(xiàn)

    本文主要介紹了python異步的ASGI與Fast Api實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Python遍歷目錄下文件、讀取、千萬條數(shù)據(jù)合并詳情

    Python遍歷目錄下文件、讀取、千萬條數(shù)據(jù)合并詳情

    這篇文章主要介紹了Python遍歷目錄下文件、讀取、千萬條數(shù)據(jù)合并詳情,對文件夾和文件進(jìn)行屬性判斷,首先對文件夾進(jìn)行遍歷,看文件夾里有什么樣的文件,讀取出文件夾中的所有文件,下面文章將詳細(xì)介紹該內(nèi)容,需要的小伙伴可以參考一下
    2022-01-01
  • GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法詳解

    GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法詳解

    這篇文章主要介紹了GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 解決python繪圖使用subplots出現(xiàn)標(biāo)題重疊的問題

    解決python繪圖使用subplots出現(xiàn)標(biāo)題重疊的問題

    這篇文章主要介紹了python繪圖使用subplots出現(xiàn)標(biāo)題重疊的問題及解決方法,本文通過實例圖文相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Python如何通過變量ID得到變量的值

    Python如何通過變量ID得到變量的值

    這篇文章主要介紹了Python如何通過變量ID得到變量的值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 如何學(xué)習(xí)Python time模塊

    如何學(xué)習(xí)Python time模塊

    在本篇文章里小編給大家分享的是關(guān)于Python time模塊知識點及用法,需要的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • python計算圓周長、面積、球體體積并畫出圓

    python計算圓周長、面積、球體體積并畫出圓

    這篇文章主要介紹了python計算圓周長、面積、球體體積并畫出圓(python3+PyObject+Gtk實現(xiàn)界面聯(lián)動),需要的朋友可以參考下
    2014-04-04
  • 最新評論