Как использовать importlib для динамического импорта QApplication из PySide2 - PullRequest
0 голосов
/ 18 июня 2019

Я могу импортировать модуль из каталога с помощью importlib, но не могу правильно использовать классы.

Без importlib я могу импортировать класс следующим образом:

>>> from PySide2.QtWidgets import QApplication
>>> app = QApplication()
>>> print(app)
<PySide2.QtWidgets.QApplication object at 0x7fe3af6a9080>

Но когда я пытаюсь импортировать его с помощью importlib (который необходим для моего динамического импорта), я получаю следующее:

>>> import sys
>>> import importlib.util
>>> package_path = '/var/tmp/PySide2/__init__.py'
>>> spec = importlib.util.spec_from_file_location('PySide2.QtWidgets.QApplication', package_path)
>>> QApplication = importlib.util.module_from_spec(spec)
>>> sys.modules[spec.name] = QApplication
>>> spec.loader.exec_module(QApplication)
>>> 
>>> app = QApplication()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable

Как заставить QApplication вести себя так же, как и в from PySide2.QtWidgets import QApplication?

Я пробовал кое-что с importlib.import_module и getattr(module, class), но я не смог понять, как использовать import_module для импорта модуля из определенного пути в файловой системе.

Я использую Python 3.5

EDIT Я также попробовал следующее:

>>> package_path = '/var/tmp/PySide2/__init__.py'
>>> spec = importlib.util.spec_from_file_location('PySide2', package_path)
>>> PySide2 = importlib.util.module_from_spec(spec)
>>> sys.modules[spec.name] = PySide2
>>> spec.loader.exec_module(PySide2)
>>> 
>>> app = PySide2.QtWidgets.QApplication()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'PySide2' has no attribute 'QtWidgets'

и

>>> QtWidgets = getattr(PySide2, 'QtWidgets')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'PySide2' has no attribute 'QtWidgets'

РЕДАКТИРОВАТЬ 2 Вот содержимое верхнего уровня каталога PySide2, который был установлен с помощью python3 -m pip install PySide2==5.12.3, а полученный каталог PySide2 был скопирован в / var / tmp /

_config.py               Qt3DRender.pyi               QtPositioning.pyi        QtUiTools.pyi
examples                 QtCharts.abi3.so             QtPrintSupport.abi3.so   QtWebChannel.abi3.so
_git_pyside_version.py   QtCharts.pyi                 QtPrintSupport.pyi       QtWebChannel.pyi
glue                     QtConcurrent.abi3.so         QtQml.abi3.so            QtWebEngine.abi3.so
include                  QtConcurrent.pyi             QtQml.pyi                QtWebEngineCore.abi3.so
__init__.py              QtCore.abi3.so               QtQuick.abi3.so          QtWebEngineCore.pyi
libpyside2.abi3.so.5.12  QtCore.pyi                   QtQuick.pyi              QtWebEngine.pyi
__pycache__              QtDataVisualization.abi3.so  QtQuickWidgets.abi3.so   QtWebEngineWidgets.abi3.so
PySide                   QtDataVisualization.pyi      QtQuickWidgets.pyi       QtWebEngineWidgets.pyi
PySide2                  QtGui.abi3.so                QtRemoteObjects.abi3.so  QtWebSockets.abi3.so
pyside2-lupdate          QtGui.pyi                    QtRemoteObjects.pyi      QtWebSockets.pyi
pyside2-rcc              QtHelp.abi3.so               QtScxml.abi3.so          QtWidgets.abi3.so
Qt                       QtHelp.pyi                   QtScxml.pyi              QtWidgets.pyi
Qt3DAnimation.abi3.so    QtLocation.abi3.so           QtSensors.abi3.so        QtX11Extras.abi3.so
Qt3DAnimation.pyi        QtLocation.pyi               QtSensors.pyi            QtX11Extras.pyi
Qt3DCore.abi3.so         QtMultimedia.abi3.so         QtSql.abi3.so            QtXml.abi3.so
Qt3DCore.pyi             QtMultimedia.pyi             QtSql.pyi                QtXmlPatterns.abi3.so
Qt3DExtras.abi3.so       QtMultimediaWidgets.abi3.so  QtSvg.abi3.so            QtXmlPatterns.pyi
Qt3DExtras.pyi           QtMultimediaWidgets.pyi      QtSvg.pyi                QtXml.pyi
Qt3DInput.abi3.so        QtNetwork.abi3.so            QtTest.abi3.so           scripts
Qt3DInput.pyi            QtNetwork.pyi                QtTest.pyi               support
Qt3DLogic.abi3.so        QtOpenGL.abi3.so             QtTextToSpeech.abi3.so   typesystems
Qt3DLogic.pyi            QtOpenGL.pyi                 QtTextToSpeech.pyi
Qt3DRender.abi3.so       QtPositioning.abi3.so        QtUiTools.abi3.so

1 Ответ

0 голосов
/ 18 июня 2019

Я думаю, что вы запутались в определении модулей.Хотя from PySide2.QtWidgets является модулем (файлом), QApplication является определением внутри этого модуля (определение класса).

Чтобы использовать import_module, необходимо указать путь к модулю .Это вернет объект модуля (как в import PySide2.QtWidgets as module).Затем вы можете использовать модуль по своему желанию:)

Пример:

import importlib

module = importlib.import_module('PySide2.QtWidgets')

QApplication = module.QApplication
app = QApplication()

Чтобы импортировать из определенного места, вы можете сделать почти так же, как в вопросе ( Импорт исходного файла напрямую ):

import importlib.util

# Note that I'm using the module path, not the package path
module_path = '/var/tmp/PySide2/QtWidgets.py'

spec = importlib.util.spec_from_file_location('PySide2.QtWidgets', module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)

QApplication = module.QApplication
app = QApplication()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...