You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单一位置维护Python包的__version__并规避依赖问题?

解决Python包版本单一源且不依赖第三方包的方案

以下是几种可行的解决方法,既能让__version__在__init__.py和setup.py中共享,又不会在安装前触发依赖项的导入:

方案1:独立的版本文件(推荐)

创建一个仅存放版本信息的独立文件,完全不依赖任何第三方包,让__init__.py和setup.py分别从这个文件导入版本。

  1. 创建版本文件:在module_a目录下新建version.py:
__version__ = "1.0.0"
  1. 修改__init__.py:先导入版本,再正常引入依赖模块:
from .version import __version__

# 这里正常导入依赖,不会影响setup.py的执行
from .bar import foo
  1. 修改setup.py:直接导入版本文件的版本,无需加载整个包:
import os
import sys

# 将包目录添加到Python路径,确保能找到version.py
sys.path.insert(0, os.path.abspath("module_a"))

from version import __version__

setup(
    name="module_a",
    version=__version__,
    install_requires=["module_b"],
    # 其他包配置...
)

这种方式的优势是逻辑清晰,版本维护完全独立,setup.py执行时不会触发任何依赖项的导入,彻底避免了依赖提前安装的问题。

方案2:使用__about__.py(规范式写法)

很多成熟项目(比如requests)会用__about__.py来集中存放版本、作者等元信息,本质和方案1一致,只是命名更符合社区规范:

  1. 创建__about__.py:
__version__ = "1.0.0"
__author__ = "Your Name"
# 其他元信息可按需添加
  1. 修改__init__.py:
from .__about__ import __version__
from .bar import foo
  1. 修改setup.py:
import os
import sys

sys.path.insert(0, os.path.abspath("module_a"))
from __about__ import __version__

setup(
    name="module_a",
    version=__version__,
    install_requires=["module_b"],
    # 其他配置...
)

方案3:在setup.py中定义版本并同步到__init__.py

如果不想新增额外文件,可以在setup.py中定义版本,通过字符串替换自动更新__init__.py里的版本,保证单一源:

  1. 修改setup.py:
import re

VERSION = "1.0.0"

# 自动同步版本到__init__.py
with open("module_a/__init__.py", "r+", encoding="utf-8") as f:
    content = f.read()
    # 替换__version__的值
    content = re.sub(r'__version__ = ".*?"', f'__version__ = "{VERSION}"', content)
    f.seek(0)
    f.write(content)
    f.truncate()

setup(
    name="module_a",
    version=VERSION,
    install_requires=["module_b"],
    # 其他配置...
)
  1. 修改__init__.py:
__version__ = "1.0.0"  # 此值会被setup.py自动更新,无需手动修改
from .bar import foo

这种方式无需额外文件,但要注意不要手动修改__init__.py里的版本,否则会被setup.py覆盖。

为什么不推荐用try-except?

你之前用try-except捕获导入异常的方式会隐藏真正的运行时错误——当用户正常使用包时,如果module_b安装失败或导入出错,异常会被静默处理,导致无法定位问题。上面的方案完全分离了版本读取和依赖导入,从根源上避免了这个问题。

内容的提问来源于stack exchange,提问作者Idan Miara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 06:05:20