Как вы можете легко выбирать между PyQt или PySide во время выполнения? - PullRequest
5 голосов
/ 08 ноября 2011

Я хотел бы сделать что-то подобное в одном исходном файле, QT.py:

import sys
import PyQt4

sys.modules["Qt"] = PyQt4

Затем импортировать этот файл в другие исходные файлы и использовать его следующим образом:

import QT
from Qt.QtCore import *

Так что я могу перейти с PyQt4 на PySide в QT.py, не затрагивая все исходные файлы (возможно, с уродливым сценарием sed). Эти модули в основном совместимы с API, и я хотел бы протестировать их оба.Есть простой способ сделать это?(Потому что способы, которые я попробовал, не работают)

Может быть, мне нужен модуль imp, но он кажется слишком низким уровнем.

Есть идеи?

Ответы [ 3 ]

4 голосов
/ 08 ноября 2011

Использовать хук импорта:

def set_qt_bindings(package):
    if package not in ('PyQt4', 'PySide'):
        raise ValueError('Unknown Qt Bindings: %s' % package)
    import __builtin__
    __import__ = __builtin__.__import__
    def hook(name, globals=None, locals=None, fromlist=None, level=-1):
        root, sep, other = name.partition('.')
        if root == 'Qt':
            name = package + sep + other
        return __import__(name, globals, locals, fromlist, level)
    __builtin__.__import__ = hook

if __name__ == '__main__':

    import sys

    if len(sys.argv) > 1:

        set_qt_bindings(sys.argv[-1])

        import Qt
        print Qt

        from Qt import QtCore
        print QtCore

        from Qt.QtGui import QWidget
        print QWidget

Выход:

$ python2 test.py PySide
<module 'PySide' from '/usr/lib/python2.7/site-packages/PySide/__init__.py'>
<module 'PySide.QtCore' from '/usr/lib/python2.7/site-packages/PySide/QtCore.so'>
<type 'PySide.QtGui.QWidget'>
$ python2 test.py PyQt4
<module 'PyQt4' from '/usr/lib/python2.7/site-packages/PyQt4/__init__.pyc'>
<module 'PyQt4.QtCore' from '/usr/lib/python2.7/site-packages/PyQt4/QtCore.so'>
<class 'PyQt4.QtGui.QWidget'>
2 голосов
/ 08 ноября 2011

обновление : Выяснили метод, более соответствующий вашим требованиям:

Вы можете структурировать свой псевдомодуль как:

Qt/
Qt/__init__.py
Qt/QtCore/__init__.py
Qt/QtGui/__init__.py

Где Qt/__init__.py:

import QtCore, QtGui

Qt/QtCore/__init__.py:

from PyQt4.QtCore import *

Qt/QtGui/__init__.py:

from PyQt4.QtGui import *

Затем в своем коде вы можете ссылаться на него следующим образом:

import sys
from Qt import QtGui
app = QtGui.QApplication(sys.argv)

from Qt.QtGui import *

window = QWidget()
window.show()

app.exec_()

Я очень рекомендую не использовать from Qt.QtGui import * в своем коде, так как импорт всего считается плохой формой в Python, поскольку вы теряете все пространства имен в процессе.

обновление : Мне нравится предложение Райана об условном импорте. Я бы порекомендовал объединить это в приведенный выше код. Например:

Qt/QtGui/__init__.py

import sys
if '--PyQt4' in sys.argv:
    from PyQt4.QtGui import *
else:
    from PySide.QtGui import *
0 голосов
/ 08 ноября 2011

Вы можете условно импортировать библиотеки.Вот немного хакерский пример, где вы проверяете аргумент командной строки «PyQt4»:

import sys

if sys.argv[-1] == 'PyQt4':
    import PyQt4
    sys.modules["Qt"] = PyQt4
else:
    import Qt
    from Qt.QtCore import *
...