古いスタイルのPythonクラスでプロパティを使用すると問題が発生しますか
-
22-07-2019 - |
質問
かなり簡単な質問。古いスタイルのクラスのプロパティを使用しても機能しないはずであると多くの場所で言及しましたが、明らかにQtクラス(PyQt4を使用)は新しいスタイルではなく、コードの一部にプロパティがあります作業中です(そして、私が知る限り、コードはどんな種類の問題も示していません)
pyqtProperty関数を実行しましたが、それに関するドキュメントを見つけることができないようです。この場合、それは良い選択肢でしょうか?
解決
propertyは、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
違いがわかりますか?本当にレガシー(古い型)クラスであるクラスでは、2番目に作成されたクラスで、メタクラスは classobj
(ISNは型のサブクラスではありません)であり、プロパティは正しく機能しません(割り当て 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のプロパティは、QtのC ++クラス(未加工のPythonプロパティではない)内からイントロスペクト可能であり、 Qt Designer フォームエディター、および Qt Creator IDE。 Pythonで持っている実行時状態の多くの種類のイントロスペクションを許可し、C ++では見逃します。一般に、Qtは動的言語の機能の一部をC ++に提供しますが、これはPyQtが同じことを行うための複数の方法を提供する唯一の領域ではありません(文字列、辞書、ファイルI / Oなども考慮してください)。これらの選択肢のほとんどについて、私が持っている主なアドバイスは、どちらか一方を選んでそれを使い続けることです。単に不快な非互換性の可能性を避けるためです。 PythonはQtよりも作業の中心であるため、私はQtバージョンよりもPythonバージョンを好む傾向があります。 PyQtからC ++ Qtへの移植を検討する場合は、PythonよりもQtバージョンの機能を好むかもしれません。
少なくとも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'>)