Форум сайта python.su
0
Вот в чем вопрос, у меня имеется класс вида
class infoLay(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, None) self.ean_edit = QtGui.QLineEdit() self.ean_edit.setDisabled(1) self.ean_edit.setMinimumWidth(70) self.ean_edit.setMaximumWidth(100) #Бла Бла бла еще много строчек кода
class infoLayMeta(type): def __init__(cls, name, bases, dict): super(infoLayMeta, cls).__init__(name, bases, dict) cls.instance = None def __call__(self,*args,**kw): if self.instance is None: self.instance = super(SingletonMeta, self).__call__(*args, **kw) return self.instance class infoLay(object): __metaclass__ = infoLayMeta def __init__(self): self.ean_edit = QtGui.QLineEdit() self.ean_edit.setDisabled(1) self.ean_edit.setMinimumWidth(70) self.ean_edit.setMaximumWidth(100) #Бла бла бла
Отредактировано Serbis (Июнь 6, 2012 19:44:23)
Офлайн
52
Вообще, можно обойтись и без метакласса. Код я вам уже приводил.
Если позарез нужен метакласс:
>>> class Singleton(type): ... def __init__(cls, name, bases, dict): ... super(Singleton, cls).__init__(name, bases, dict) ... cls.instance = None ... ... def __call__(cls, *args, **kwargs): ... if cls.instance is None: ... cls.instance = super(Singleton, cls).__call__(*args, **kwargs) ... return cls.instance ... >>> class A(object): ... __metaclass__ = Singleton ... >>> class B(object): ... pass ... >>> foo, bar = B(), B() >>> foo == bar False >>> foo, bar = A(), A() >>> foo == bar True >>> id(foo), id(bar) (174132204, 174132204)
Отредактировано fata1ex (Июнь 6, 2012 21:01:14)
Офлайн
173
SerbisЦелесообразно ли? Может проще в модуле сделать функцию, которая будет возвращать инстанс, создавая его если еще не создан?
Суть перевода в метакласс - создание синглтона.
import noconflict class ListWidget(QtGui.QListWidget, collections.MutableSequence): __metaclass__ = noconflict.classmaker() ...
class InfoLayMetaHelper(object): __metaclass__ = infoLayMeta class infoLay(QtGui.QWidget, InfoLayMetaHelper): __metaclass__ = noconflict.classmaker() def __init__(self): self.ean_edit = QtGui.QLineEdit() self.ean_edit.setDisabled(1) self.ean_edit.setMinimumWidth(70) self.ean_edit.setMaximumWidth(100) # test assert infoLay() is infoLay()
Офлайн
72
Я дико извиняюсь, но почему нельзя просто создать экземпляр класса на уровне модуля? Вроде же гарантировано, что код уровня модуля выполнится один раз?
Офлайн
173
PooHВ общем случае можно, и это удобно. Но если это наследник QWidget, его нельзя создать до создания экземпляра QApplication.
Я дико извиняюсь, но почему нельзя просто создать экземпляр класса на уровне модуля? Вроде же гарантировано, что код уровня модуля выполнится один раз?
from PySide import QtGui w = QtGui.QWidget() print "Ok"
QWidget: Must construct a QApplication before a QPaintDevice
Офлайн
0
reclosedevSerbisЦелесообразно ли? Может проще в модуле сделать функцию, которая будет возвращать инстанс, создавая его если еще не создан?
Суть перевода в метакласс - создание синглтона.
Причина в том, что классы из PySide/PyQt содержат свой метакласс.
Когда я пытался унаследоваться от QtGui.QListWidget и collections.MutableSequence, помогло вот это:
http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/import noconflict class ListWidget(QtGui.QListWidget, collections.MutableSequence): __metaclass__ = noconflict.classmaker() ...
Синглтон,с использованием noconflict будет выглядеть примерно так (если очень сильно нужен):class InfoLayMetaHelper(object): __metaclass__ = infoLayMeta class infoLay(QtGui.QWidget, InfoLayMetaHelper): __metaclass__ = noconflict.classmaker() def __init__(self): self.ean_edit = QtGui.QLineEdit() self.ean_edit.setDisabled(1) self.ean_edit.setMinimumWidth(70) self.ean_edit.setMaximumWidth(100) # test assert infoLay() is infoLay()
Офлайн
173
SerbisМожет забыли убрать проверочный код?
но есть одно но - конструктор класса infoLay отрабатывается сразу после запуска цикла программы, в результате:
QWidget: Must construct a QApplication before a QPaintDevice
Аварийный останов
# test assert infoLay() is infoLay()
Офлайн