从文件中获取版本值而不使用导入加载源?

2024-10-03 06:18:17 发布

您现在位置:Python中文网/ 问答频道 /正文

我以前做过以下操作来获取版本字符串:

>>> filepath = './somemodule/__init__.py'
>>> name = 'dummy'
>>> module_source = imp.load_source(name, filepath)
>>> module_source.__version__
1.0.0

现在,当imp在python3中被弃用时(我使用的是3.7.1),用什么替代load_source呢?它只需要std库?你知道吗

这在我看来有点复杂,load_module实际上是不赞成的:

>>> from importlib.machinery import SourceFileLoader
>>> loaded = SourceFileLoader(name, filepath).load_module()
>>> loaded.__version__
1.0.0

编辑#1:

这在Import arbitrary python source file. (Python 3.3+)中讨论过,其中一个解决方案是:

>>> loader = importlib.machinery.SourceFileLoader(name, filepath)
>>> mod = types.ModuleType(loader.name)
>>> loader.exec_module(mod)
>>> mod.__version__
1.0.0

Tags: 字符串name版本modsourceversionloadloader
2条回答

如果您只是想导入版本,我通常会选择使用utils提供的werkzeug;我相信您可以使用以下内容:

from werkzeug.utils import import_string
version = import_string('module.__version__', silent=True)

您还可以将silent作为bool传递,这将告诉函数忽略导入错误,并在遇到任何错误时返回None。你知道吗

导入模块的“舒适”方法是使用^{}。对于所有实际用途,这与使用import语句一样。但是,它不能导入不在sys.path中的任意文件,因此它不适用于您的用例。你知道吗

要直接导入文件,importlib文档provides使用以下方法:

import importlib.util
import sys

# For illustrative purposes.
import tokenize
file_path = tokenize.__file__
module_name = tokenize.__name__

spec = importlib.util.spec_from_file_location(module_name, file_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
# Optional; only necessary if you want to be able to import the module
# by name later.
sys.modules[module_name] = module

最后,有一点建议:我建议将版本字符串放在一个单独的文本文件中,称为(比如)__version__.txt,然后从__init__.py和其他需要知道版本的文件中加载它。这样,就不需要执行Python代码来读取版本号。您可以使用__init__.py中的^{}从这些文件加载数据,并在从另一个模块调用时用合适的值替换__package__,或者直接打开文件。get_data()返回bytes;您可能需要对返回值调用^{},将其转换为字符串。你知道吗

pkgutil.get_data()似乎是一种迂回的方法,但如果您的代码是imported from a ZIP file或以其他奇特的方式安装的,那么它是必需的。如果您的代码是namespace package或是以一种特别不寻常的方式安装的,get_data()可能无法工作并返回None,因此您应该检查这种情况并避免崩溃。)

相关问题 更多 >