<p>导入模块的“舒适”方法是使用<a href="https://docs.python.org/3/library/importlib.html#importlib.import_module" rel="nofollow noreferrer">^{<cd1>}</a>。对于所有实际用途,这与使用<code>import</code>语句一样。但是,它不能导入不在<code>sys.path</code>中的任意文件,因此它不适用于您的用例。你知道吗</p>
<p>要直接导入文件,<code>importlib</code>文档<a href="https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly" rel="nofollow noreferrer">provides</a>使用以下方法:</p>
<blockquote>
<pre><code>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
</code></pre>
</blockquote>
<p>最后,有一点建议:我建议将版本字符串放在一个单独的文本文件中,称为(比如)<code>__version__.txt</code>,然后从<code>__init__.py</code>和其他需要知道版本的文件中加载它。这样,就不需要执行Python代码来读取版本号。您可以使用<code>__init__.py</code>中的<a href="https://docs.python.org/3/library/pkgutil.html#pkgutil.get_data" rel="nofollow noreferrer">^{<cd7>}</a>从这些文件加载数据,并在从另一个模块调用时用合适的值替换<code>__package__</code>,或者直接打开文件。<code>get_data()</code>返回<code>bytes</code>;您可能需要对返回值调用<a href="https://docs.python.org/3/library/stdtypes.html#bytes.decode" rel="nofollow noreferrer">^{<cd12>}</a>,将其转换为字符串。你知道吗</p>
<p>(<code>pkgutil.get_data()</code>似乎是一种迂回的方法,但如果您的代码是<a href="https://docs.python.org/3/library/zipimport.html" rel="nofollow noreferrer">imported from a ZIP file</a>或以其他奇特的方式安装的,那么它是必需的。如果您的代码是<a href="https://docs.python.org/3/glossary.html#term-namespace-package" rel="nofollow noreferrer">namespace package</a>或是以一种特别不寻常的方式安装的,<code>get_data()</code>可能无法工作并返回<code>None</code>,因此您应该检查这种情况并避免崩溃。)</p>