Python использует importlib для импорта модуля из каталога пакетов - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь импортировать PySide2 динамически с importlib, потому что статически с import недостаточно для моего приложения.Мне нужен importlib, потому что в конце он будет использоваться с pyinstaller для создания одного исполняемого файла, который может динамически импортировать PySide2, а не только из одного исполняемого файла.

Я скопировал весь каталог пакета PySide2, который был загружен спип.Эта версия PySide2 более старая, чем та, которую я использую по умолчанию, и когда в моем исходном каталоге присутствует каталог "PySide2", я хочу использовать его вместо этого.

Основываясь на ответе в этой записи , у меня есть следующий код для выполнения импорта:

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

Я не понимаю, почему он говорит "имя 'PySide2' не определено ", когда оно появляется в sys.modules.

1 Ответ

1 голос
/ 16 июня 2019

Из документации , NameError вызывается, когда локальное или глобальное имя не найдено.

Для стандартного оператора импорта я буду делать следующие вещи:

  • Найти и загрузить модуль
  • Обновить sys.modules
  • Обновить глобальныедиктуйте имя переменной, указывающее на фактический объект модуля для import foo, обновляйте несколько переменных, когда оно import * from something (также проверьте __all__ модуля)

Здесь вы уже сделали первый2 шага вручную, вам нужно всего лишь добавить:

PySide2 = module
...