I would like to do something like this in one source file, QT.py:
import sys
import PyQt4
sys.modules["Qt"] = PyQt4
Then import this file in the other source files, and use it like this:
import QT
from Qt.QtCore import *
So I can change from PyQt4 to PySide in QT.py without touching all the source files (with a possibly ugly sed script)
These modules are mostly API compatibile and I would like to test them both. Is there an easy way to do this? (Because the ways I tried are not working)
Maybe the I need imp
module, but it seems too low level.
update: Figured out method more in line with your requirements:
You can structure your pseudo-module as:
Qt/
Qt/__init__.py
Qt/QtCore/__init__.py
Qt/QtGui/__init__.py
Where Qt/__init__.py
is:
import QtCore, QtGui
Qt/QtCore/__init__.py
is:
from PyQt4.QtCore import *
Qt/QtGui/__init__.py
is:
from PyQt4.QtGui import *
Then, in your code, you can reference it as follows:
import sys
from Qt import QtGui
app = QtGui.QApplication(sys.argv)
from Qt.QtGui import *
window = QWidget()
window.show()
app.exec_()
I highly recommend against using from Qt.QtGui import *
in your code as importing everything is considered bad form in Python since you lose all namespaces in the process.
update:
I like Ryan's suggestion of conditional imports. I'd recommend combining that into the above code. For example:
Qt/QtGui/__init__.py
:
import sys
if '--PyQt4' in sys.argv:
from PyQt4.QtGui import *
else:
from PySide.QtGui import *
Use an import hook:
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
Output:
$ 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'>
You can conditionally import libraries. Here is a bit of a hacky example, where you check for a command-line argument of "PyQt4":
import sys
if sys.argv[-1] == 'PyQt4':
import PyQt4
sys.modules["Qt"] = PyQt4
else:
import Qt
from Qt.QtCore import *