Python 使用 importlib 从包目录导入模块
Python use importlib to import a module from a package directory
我正在尝试使用 importlib
动态导入 PySide2,因为使用 import
静态导入 PySide2 对我的应用程序来说是不够的。我需要 importlib 因为最后它将与 pyinstaller 一起使用来创建一个可以动态导入 PySide2 的可执行文件,而不仅仅是从单个可执行文件。
我已经复制了用 pip 下载的整个 PySide2 包目录。这个 PySide2 版本比我默认使用的版本旧,当 "PySide2" 目录出现在我的源目录中时,我想改用它。
根据this post中的答案,我有以下代码来执行导入:
import os, sys
print("Import test")
if os.path.isdir('./PySide2/'):
print('Importing local PySide2')
import importlib.util
MODULE_PATH = "./PySide2/__init__.py"
MODULE_NAME = "PySide2"
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
print("spec.name is " + str(spec.name))
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
print(sys.modules)
spec.loader.exec_module(module)
print(PySide2.__version__)
else:
print('Importing system PySide2')
import PySide2
print(PySide2.__version__)
但是当我 运行 它时,我得到 NameError: name 'PySide2' is not defined
,即使我在 sys.modules 中看到 PySide2 存在(在下面的输出中一直向右滚动到看到它存在):
$ python importTest.py
Import test
Importing local PySide2
spec.name is PySide2
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_thread': <module '_thread' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_weakref': <module '_weakref' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, '_frozen_importlib_external': <module 'importlib._bootstrap_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, 'encodings': <module 'encodings' from '/usr/lib/python3.7/encodings/__init__.py'>, 'codecs': <module 'codecs' from '/usr/lib/python3.7/codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from '/usr/lib/python3.7/encodings/aliases.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/usr/lib/python3.7/encodings/utf_8.py'>, '_signal': <module '_signal' (built-in)>, '__main__': <module '__main__' from 'importTest.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from '/usr/lib/python3.7/encodings/latin_1.py'>, 'io': <module 'io' from '/usr/lib/python3.7/io.py'>, 'abc': <module 'abc' from '/usr/lib/python3.7/abc.py'>, '_abc': <module '_abc' (built-in)>, 'site': <module 'site' from '/usr/lib/python3.7/site.py'>, 'os': <module 'os' from '/usr/lib/python3.7/os.py'>, 'stat': <module 'stat' from '/usr/lib/python3.7/stat.py'>, '_stat': <module '_stat' (built-in)>, 'posixpath': <module 'posixpath' from '/usr/lib/python3.7/posixpath.py'>, 'genericpath': <module 'genericpath' from '/usr/lib/python3.7/genericpath.py'>, 'os.path': <module 'posixpath' from '/usr/lib/python3.7/posixpath.py'>, '_collections_abc': <module '_collections_abc' from '/usr/lib/python3.7/_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from '/usr/lib/python3.7/_sitebuiltins.py'>, 'sitecustomize': <module 'sitecustomize' from '/usr/lib/python3.7/sitecustomize.py'>, 'importlib': <module 'importlib' from '/usr/lib/python3.7/importlib/__init__.py'>, 'importlib._bootstrap': <module 'importlib._bootstrap' (frozen)>, 'importlib._bootstrap_external': <module 'importlib._bootstrap_external' (frozen)>, 'types': <module 'types' from '/usr/lib/python3.7/types.py'>, 'warnings': <module 'warnings' from '/usr/lib/python3.7/warnings.py'>, 'importlib.util': <module 'importlib.util' from '/usr/lib/python3.7/importlib/util.py'>, 'importlib.abc': <module 'importlib.abc' from '/usr/lib/python3.7/importlib/abc.py'>, 'importlib.machinery': <module 'importlib.machinery' from '/usr/lib/python3.7/importlib/machinery.py'>, 'contextlib': <module 'contextlib' from '/usr/lib/python3.7/contextlib.py'>, 'collections': <module 'collections' from '/usr/lib/python3.7/collections/__init__.py'>, 'operator': <module 'operator' from '/usr/lib/python3.7/operator.py'>, '_operator': <module '_operator' (built-in)>, 'keyword': <module 'keyword' from '/usr/lib/python3.7/keyword.py'>, 'heapq': <module 'heapq' from '/usr/lib/python3.7/heapq.py'>, '_heapq': <module '_heapq' (built-in)>, 'itertools': <module 'itertools' (built-in)>, 'reprlib': <module 'reprlib' from '/usr/lib/python3.7/reprlib.py'>, '_collections': <module '_collections' (built-in)>, 'functools': <module 'functools' from '/usr/lib/python3.7/functools.py'>, '_functools': <module '_functools' (built-in)>, 'PySide2': <module 'PySide2' from './PySide2/__init__.py'>}
Traceback (most recent call last):
File "importTest.py", line 17, in <module>
print(PySide2.__version__)
NameError: name 'PySide2' is not defined
我不明白为什么在 sys.modules.
中显示 "name 'PySide2' is not define"
从 documentation 开始,当找不到本地或全局名称时会引发 NameError
。
对于标准导入语句,
它会做以下事情:
- 查找并加载模块
- 更新sys.modules
- 使用指向
import foo
的实际模块对象的变量名称更新全局字典,当 import * from something
时更新多个变量(同时检查模块的 __all__
)
这里你已经手动完成了前2个步骤,你只需要添加:
PySide2 = module
我正在尝试使用 importlib
动态导入 PySide2,因为使用 import
静态导入 PySide2 对我的应用程序来说是不够的。我需要 importlib 因为最后它将与 pyinstaller 一起使用来创建一个可以动态导入 PySide2 的可执行文件,而不仅仅是从单个可执行文件。
我已经复制了用 pip 下载的整个 PySide2 包目录。这个 PySide2 版本比我默认使用的版本旧,当 "PySide2" 目录出现在我的源目录中时,我想改用它。
根据this post中的答案,我有以下代码来执行导入:
import os, sys
print("Import test")
if os.path.isdir('./PySide2/'):
print('Importing local PySide2')
import importlib.util
MODULE_PATH = "./PySide2/__init__.py"
MODULE_NAME = "PySide2"
spec = importlib.util.spec_from_file_location(MODULE_NAME, MODULE_PATH)
print("spec.name is " + str(spec.name))
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
print(sys.modules)
spec.loader.exec_module(module)
print(PySide2.__version__)
else:
print('Importing system PySide2')
import PySide2
print(PySide2.__version__)
但是当我 运行 它时,我得到 NameError: name 'PySide2' is not defined
,即使我在 sys.modules 中看到 PySide2 存在(在下面的输出中一直向右滚动到看到它存在):
$ python importTest.py
Import test
Importing local PySide2
spec.name is PySide2
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_thread': <module '_thread' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_weakref': <module '_weakref' (built-in)>, 'zipimport': <module 'zipimport' (built-in)>, '_frozen_importlib_external': <module 'importlib._bootstrap_external' (frozen)>, '_io': <module 'io' (built-in)>, 'marshal': <module 'marshal' (built-in)>, 'posix': <module 'posix' (built-in)>, 'encodings': <module 'encodings' from '/usr/lib/python3.7/encodings/__init__.py'>, 'codecs': <module 'codecs' from '/usr/lib/python3.7/codecs.py'>, '_codecs': <module '_codecs' (built-in)>, 'encodings.aliases': <module 'encodings.aliases' from '/usr/lib/python3.7/encodings/aliases.py'>, 'encodings.utf_8': <module 'encodings.utf_8' from '/usr/lib/python3.7/encodings/utf_8.py'>, '_signal': <module '_signal' (built-in)>, '__main__': <module '__main__' from 'importTest.py'>, 'encodings.latin_1': <module 'encodings.latin_1' from '/usr/lib/python3.7/encodings/latin_1.py'>, 'io': <module 'io' from '/usr/lib/python3.7/io.py'>, 'abc': <module 'abc' from '/usr/lib/python3.7/abc.py'>, '_abc': <module '_abc' (built-in)>, 'site': <module 'site' from '/usr/lib/python3.7/site.py'>, 'os': <module 'os' from '/usr/lib/python3.7/os.py'>, 'stat': <module 'stat' from '/usr/lib/python3.7/stat.py'>, '_stat': <module '_stat' (built-in)>, 'posixpath': <module 'posixpath' from '/usr/lib/python3.7/posixpath.py'>, 'genericpath': <module 'genericpath' from '/usr/lib/python3.7/genericpath.py'>, 'os.path': <module 'posixpath' from '/usr/lib/python3.7/posixpath.py'>, '_collections_abc': <module '_collections_abc' from '/usr/lib/python3.7/_collections_abc.py'>, '_sitebuiltins': <module '_sitebuiltins' from '/usr/lib/python3.7/_sitebuiltins.py'>, 'sitecustomize': <module 'sitecustomize' from '/usr/lib/python3.7/sitecustomize.py'>, 'importlib': <module 'importlib' from '/usr/lib/python3.7/importlib/__init__.py'>, 'importlib._bootstrap': <module 'importlib._bootstrap' (frozen)>, 'importlib._bootstrap_external': <module 'importlib._bootstrap_external' (frozen)>, 'types': <module 'types' from '/usr/lib/python3.7/types.py'>, 'warnings': <module 'warnings' from '/usr/lib/python3.7/warnings.py'>, 'importlib.util': <module 'importlib.util' from '/usr/lib/python3.7/importlib/util.py'>, 'importlib.abc': <module 'importlib.abc' from '/usr/lib/python3.7/importlib/abc.py'>, 'importlib.machinery': <module 'importlib.machinery' from '/usr/lib/python3.7/importlib/machinery.py'>, 'contextlib': <module 'contextlib' from '/usr/lib/python3.7/contextlib.py'>, 'collections': <module 'collections' from '/usr/lib/python3.7/collections/__init__.py'>, 'operator': <module 'operator' from '/usr/lib/python3.7/operator.py'>, '_operator': <module '_operator' (built-in)>, 'keyword': <module 'keyword' from '/usr/lib/python3.7/keyword.py'>, 'heapq': <module 'heapq' from '/usr/lib/python3.7/heapq.py'>, '_heapq': <module '_heapq' (built-in)>, 'itertools': <module 'itertools' (built-in)>, 'reprlib': <module 'reprlib' from '/usr/lib/python3.7/reprlib.py'>, '_collections': <module '_collections' (built-in)>, 'functools': <module 'functools' from '/usr/lib/python3.7/functools.py'>, '_functools': <module '_functools' (built-in)>, 'PySide2': <module 'PySide2' from './PySide2/__init__.py'>}
Traceback (most recent call last):
File "importTest.py", line 17, in <module>
print(PySide2.__version__)
NameError: name 'PySide2' is not defined
我不明白为什么在 sys.modules.
中显示 "name 'PySide2' is not define"从 documentation 开始,当找不到本地或全局名称时会引发 NameError
。
对于标准导入语句, 它会做以下事情:
- 查找并加载模块
- 更新sys.modules
- 使用指向
import foo
的实际模块对象的变量名称更新全局字典,当import * from something
时更新多个变量(同时检查模块的__all__
)
这里你已经手动完成了前2个步骤,你只需要添加:
PySide2 = module