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

使用Poetry管理依赖,如何避免硬编码包名获取Python包版本?

解决方法

针对你的需求,这里提供几种靠谱的实现方式:

方案2:解析pyproject.toml提取包名

Python 3.11及以上版本自带tomllib库,可直接解析TOML文件;如果是3.11以下版本,需要先安装第三方库tomli(注意结尾是i),然后把代码里的tomllib替换成tomli。

具体代码

import tomllib  # Python 3.11+;低版本用import tomli as tomllib
import importlib.metadata
import os

def get_package_name():
    # 从当前文件目录向上查找pyproject.toml,适配不同的脚本位置
    current_dir = os.path.abspath(os.path.dirname(__file__))
    while current_dir != os.path.dirname(current_dir):
        pyproject_path = os.path.join(current_dir, "pyproject.toml")
        if os.path.exists(pyproject_path):
            with open(pyproject_path, "rb") as f:
                config = tomllib.load(f)
            # Poetry管理的包名在tool.poetry.name字段下
            return config["tool"]["poetry"]["name"]
        current_dir = os.path.dirname(current_dir)
    raise FileNotFoundError("项目根目录未找到pyproject.toml文件")

# 获取并打印版本
pkg_name = get_package_name()
version = importlib.metadata.version(pkg_name)
print(f"当前包版本:{version}")

更稳妥的替代方案:在包内定义包名

如果不想做配置文件解析,还有个更简单可靠的方法——在你的包的__init__.py里直接定义包名:

# 比如你的包是mypackage,就在mypackage/__init__.py里加:
__package_name__ = "mypackage"

之后在需要获取版本的地方直接引用:

import importlib.metadata
from mypackage import __package_name__

version = importlib.metadata.version(__package_name__)

这种方式不用处理文件路径问题,也不会出现解析错误,是Python包的常规做法。

补充:为什么方案1不可靠

用__name__.split(".")[0]的问题在于:如果代码是直接执行的脚本(比如python my_script.py),__name__的值会是__main__,拆分后完全不对;另外如果包有多层嵌套结构,这种提取方式也可能拿到错误的顶层包名,所以确实不推荐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:57:09