Python使用importlib从包目录中导入模块 [英] Python use importlib to import a module from a package directory

查看:162
本文介绍了Python使用importlib从包目录中导入模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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's import * 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从包目录中导入模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆