问题描述
我正在尝试使用importlib
动态导入PySide2,因为使用import
静态地导入PySide2对于我的应用程序是不够的.我需要importlib,因为最后它将与pyinstaller一起使用,以创建可以动态导入PySide2的单个可执行文件,而不仅仅是从单个可执行文件导入.
I'm trying to import PySide2 dynamically with importlib
, because statically with import
isn't sufficient for my application. I need importlib because in the end it will be used with pyinstaller to create a single executable that can import PySide2 dynamically, not just from the single executable.
我已经复制了一个完整的PySide2软件包目录,该目录是通过pip下载的.这个PySide2版本比我默认使用的版本要旧,并且当源目录中存在"PySide2"目录时,我想改用它.
I've copied an entire PySide2 package directory that was downloaded with pip. This PySide2 version is older than the one that I'm using by default, and when the "PySide2" directory is present in my source directory, I want to use it instead.
根据这篇文章中的答案,我使用以下代码来执行导入:
Based on the answer in this post, I have the following code to perform the import:
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__)
但是,当我运行它时,即使在sys.modules中看到存在PySide2(在下面的输出中一直滚动到右侧,也可以看到它),我仍然得到NameError: name 'PySide2' is not defined
:
But when I run it, I get NameError: name 'PySide2' is not defined
, even though I see in sys.modules that PySide2 is present (scroll all the way to the right in the output below to see it is present):
$ 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中时,我不明白为什么它说名称'PySide2'未定义".
I don't understand why it says "name 'PySide2' is not define" when it appears in the sys.modules.
推荐答案
来自文档,如果找不到本地或全局名称,则会引发NameError
.
From the documentation, NameError
is raised when a local or global name is not found.
对于标准导入声明,它将执行以下操作:
For the standard import statement,it will do following things:
- 查找并添加加载模块
- 更新sys.modules
- 用指向
import foo
的实际模块对象的变量名更新全局字典,在import * from something
时更新多个变量(还要检查模块的__all__
)
- Find & Load the module
- Update sys.modules
- Update global dict with a variable name pointing to actual module object for
import foo
, update multiple variables when it'simport * from something
(also check__all__
of the module)
在这里,您已经手动完成了前2个步骤,只需添加:
Here you've already done the first 2 steps manually, you only need to add:
PySide2 = module
这篇关于Python使用importlib从包目录中导入模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!