我以前已经完成了以下操作以获取版本字符串:
>>> filepath = './somemodule/__init__.py'
>>> name = 'dummy'
>>> module_source = imp.load_source(name, filepath)
>>> module_source.__version__
1.0.0
现在,当在Python 3中不推荐使用imp
时(我在3.7.1上),什么是load_source
的好替代品呢?它只需要std库?
在我看来这有点令人费解,load_module
实际上已被弃用:
>>> from importlib.machinery import SourceFileLoader
>>> loaded = SourceFileLoader(name, filepath).load_module()
>>> loaded.__version__
1.0.0
这在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
答案 0 :(得分:0)
如果您只是想导入版本,我通常会选择使用utils
提供的werkzeug
;我相信您可以使用以下内容:
from werkzeug.utils import import_string
version = import_string('module.__version__', silent=True)
您还可以将silent
作为bool
传递,这将告诉该函数忽略导入错误,如果遇到任何错误,则返回None
。
答案 1 :(得分:0)
导入模块的“舒适”方式是使用importlib.import_module()
。出于所有实际目的,这就像使用@api.model
def default_department_id(self):
# just an example! implement your own default
# always return a recordset (even an empty one)!
return self.env['my.department.model'].search([], limit=1)
department_id = fields.Many2one(
comodel_name="my.department.model", default=default_department_id)
语句一样。但是,它无法导入不在import
中的任意文件,因此不适用于您的用例。
要直接导入文件,请sys.path
文档provides此食谱:
importlib
最后一点建议:我建议将版本字符串放在一个单独的文本文件中,该文件称为(例如)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
以及需要知道版本的任何其他文件中加载。这样,您无需执行Python代码即可读取版本号。您可以使用__init__.py
中的pkgutil.get_data(__package__, '__version__.txt')
从此类文件中加载数据,并在从另一个模块调用时将__init__.py
替换为合适的值,或直接打开文件。 __package__
返回get_data()
;您可能要在返回值上调用.decode()
,以将其转换为字符串。
({bytes
似乎是一种绕行的方式,但是如果您的代码是imported from a ZIP file或以其他特殊方式安装,则是必需的。如果您的代码是namespace package或是用特别不寻常的方式安装的,pkgutil.get_data()
可能无法正常工作并返回get_data()
,因此您应该检查这种情况并避免崩溃。)