跳转到内容

搜索

Python 语言的命名约定:__init__.py vs __main__.py / main.py

拾知 4 min read

__init__.py vs __main__.py/main.py:「__init__.py」 将目录初始化为可导入的包,而 「main.py」 (或包的 「__main__.py」 )作为运行应用程序的主要可执行入口点。

核心区别

特性__init__.pymain.py/__main__.py
角色包初始化与暴露 API项目执行与入口点
触发时机当你 import 目录时自动触发通过 CLI 手动运行( python main.py
典型内容干净的 API 导出;初始化配置编排逻辑,CLI 解析,启动应用

__init__.py:包管理器

__init__.py 文件告诉 Python 应将一个目录视为常规包。当有人导入(import)你的目录时,这个文件会在后台自动执行。

  • 初始化代码:它设置包级别的变量或连接池。
  • 暴露更干净的 API:你无需强迫用户输入 from mypackage.module.submodule import MyClass ,可以直接在 __init__.py 中导入 MyClass 。用户随后可以编写 from mypackage import MyClass
  • 定义包范围:您可以在其中使用 __all__ 变量来控制在通配符( from package import * )操作期间暴露的内容。

一个例子

项目结构

my_project/
└── my_package/
    ├── __init__.py      # 包的初始化文件
    ├── core.py          # 核心业务逻辑模块
    └── utils.py         # 工具函数模块

编写核心业务函数:my_package/core.py

def calculate_score(data):
    return sum(data) * 1.5

编写常用的工具函数:my_package/utils.py

def format_date(timestamp):
    return f"Date: {timestamp}"

在初始化文件中,将两个模块的函数暴露到“包级别”

# 1. 定义包级别的全局变量
__version__ = "1.0.0"
AUTHOR = "Developer"
 
# 2. 预先导入子模块中的函数(提升到包的顶级命名空间)
from .core import calculate_score
from .utils import format_date
 
# 3. 显式定义允许导出的内容(可选,但推荐)
__all__ = ["calculate_score", "format_date", "__version__"]
 

如果__init__.py 为空,调用者必须知道具体的文件名,路径较深

from my_package.core import calculate_score
from my_package.utils import format_date
 
print(calculate_score([1, 2, 3]))

如果配置了 __init__.py,调用者无需关心函数具体在哪个隐藏的文件里,直接从包导入

# 一行搞定所有导入
from my_package import calculate_score, format_date, __version__
 
print(__version__)                     # 输出: 1.0.0
print(calculate_score([1, 2, 3]))     # 输出: 9.0

main.py__main__.py:项目执行入口

这些文件旨在启动应用程序运行时。

  • main.py :这是典型应用程序存储库中项目执行文件的标准命名约定。通过明确指向它来执行它: python main.py
  • __main__.py : 这是一个特殊内部文件,用于当你想将整个包作为脚本运行时执行。运行 python -m mypackage 会告诉 Python 在包文件夹内查找并自动执行 __main__.py

示例项目结构

这是它们在应用程序中并排工作时的一般外观:

my_project/

├── main.py                 # Application entry point (runs the whole app)
└── my_package/             # An importable directory package
    ├── __init__.py         # Executes on `import my_package`
    ├── __main__.py         # Executes on `python -m my_package`
    ├── database.py
    └── utils.py
 

总结

  • 除非你想让它在每次有人从那个文件夹导入东西时都运行,否则不要在 __init__.py 中包含代码。
  • __init__.py 中的初始化逻辑保持轻量。
  • 将脚本执行代码严格保持在 main.py__main__.py 内。