Вызывает ли проблема использование свойств в классах Python старого стиля?
-
22-07-2019 - |
Вопрос
Довольно простой вопрос. Я видел во многих местах упоминание о том, что использование свойств в классе старого стиля не должно работать, но, очевидно, классы Qt (через PyQt4) не являются новым стилем, и в некоторых кодах есть свойства некоторых из них. я работаю с (и, насколько я знаю, код не показывает каких-либо проблем)
Я натолкнулся на функцию pyqtProperty, но, похоже, не могу найти какую-либо документацию по этому поводу. Будет ли это хорошей альтернативой в этом случае?
Решение
работает, потому что QObject имеет метакласс, который заботится о них. Посмотрите на эту небольшую вариацию кода @ quark ...
from PyQt4.QtCore import QObject
def makec(base):
class X( base ):
def __init__(self):
self.__x = 10
def get_x(self):
print 'getting',
return self.__x
def set_x(self, x):
print 'setting', x
self.__x = x
x = property(get_x, set_x)
print 'made class of mcl', type(X), issubclass(type(X), type)
return X
class old: pass
for base in (QObject, old):
X = makec(base)
x = X()
print x.x # Should be 10
x.x = 30
print x.x # Should be 30
при этом запускается:
made class of mcl <type 'PyQt4.QtCore.pyqtWrapperType'> True
getting 10
setting 30
getting 30
made class of mcl <type 'classobj'> False
getting 10
30
видите разницу? В классе, который действительно является устаревшим (старого типа) классом, созданным во второй раз, метаклассом является classobj
(который НЕ является подклассом типа), и свойства не работают правильно (назначение xx
обходит свойство, и после этого получение xx
также больше не видит свойство). Но в первом случае, в случае Qt, есть другой метакласс, и он является подклассом типа (поэтому не совсем правильно говорить, что класс «не новый стиль»!), И поэтому все работает правильно. . р>
Другие советы
Свойства сортировки Python, по моему опыту, прекрасно работают с объектами PyQt4. Я не знаю, явно ли они поддерживаются PyQt4 или нет, есть ли какие-то скрытые ошибки, но я никогда не видел, чтобы они плохо себя вели. Вот пример использования PyQt 4.4 и Python 2.5:
from PyQt4.QtCore import QObject
class X( QObject ):
def __init__(self):
self.__x = 10
def get_x(self):
return self.__x
def set_x(self, x):
self.__x = x
x = property(get_x, set_x)
x = X()
print x.x # Should be 10
x.x = 30
print x.x # Should be 30
pyqtProperty
разрешает использовать систему свойств Qt это не то же самое, что Python. Свойства Qt интроспективны из классов C ++ Qt (которые не являются необработанными свойствами Python) и используются Qt для таких вещей, как их редактор форм Qt Designer и Qt Creator IDE. Они допускают много видов самоанализа состояния времени выполнения , которое есть у вас в Python и отсутствует в C ++. В общем, Qt предоставляет некоторые возможности динамических языков для C ++, и это не единственная область, где PyQt предоставляет больше, чем один способ сделать то же самое (рассмотрим также строки, словари, файловый ввод-вывод и т. Д.). С большинством из этих выборов главный совет, который я имею, состоит в том, чтобы просто выбрать одну или другую сторону и придерживаться ее, просто чтобы избежать возможности некоторой неприятной несовместимости. Я склоняюсь к тому, чтобы предпочесть версию Python, а не версию Qt, потому что Python является более ядром в моей работе, чем Qt. Если вы собираетесь переносить что-либо из PyQt обратно в C ++ Qt, вы можете предпочесть версию Qt функции, а не версию Python.
По крайней мере в PyQt4.5 классы Qt, безусловно, являются новыми объектами стиля, как видно из порядка разрешения их методов:
from PyQt4 import QtGui
print QtGui.QWidget.__mro__
(<class 'PyQt4.QtGui.QWidget'>, <class 'PyQt4.QtCore.QObject'>, <type 'sip.wrapper'>, <class 'PyQt4.QtGui.QPaintDevice'>, <type 'sip.simplewrapper'>, <type 'object'>)