هل استخدام خصائص على الطراز القديم تسبب مشاكل الطبقة الثعبان

StackOverflow https://stackoverflow.com/questions/1230383

  •  22-07-2019
  •  | 
  •  

سؤال

وسؤال بسيط جدا. لقد رأيت ذلك مذكور في العديد من الأماكن التي تستخدم الخصائص على فئة من الطراز القديم لا ينبغي أن تعمل، ولكن على ما يبدو الطبقات كيو تي (من خلال PyQt4) ليست جديدة على غرار وهناك خصائص على عدد قليل منهم في رمز I 'م العمل مع (وبقدر ما أعرف رمز لا يظهر أي نوع من المشاكل)

وأنا لم تعمل عبر وظيفة pyqtProperty، ولكن لا يمكنني العثور على ما يبدو أي وثائق حول هذا الموضوع. سيكون بديل جيد في هذه الحالة؟

هل كانت مفيدة؟

المحلول

والممتلكات تعمل لديها QObject metaclass أن يعتني بهم. يشهد هذا الاختلاف صغير على كود @ كوارك و...:

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

وترى الفرق؟ في الفئة التي في الحقيقة إرث (النوع القديم) فئة، أدلى واحد للمرة الثانية، metaclass هو classobj (وهي ليست فئة فرعية من نوع) والخصائص لا تعمل الحق (تعيين x.x يتجاوز الممتلكات، وبعد أن x.x الحصول على لا يرى الملكية أي أكثر من ذلك أيضا). ولكن في الحالة الأولى، حالة كيو تي، وهناك metaclass مختلفة، وأنه هو فئة فرعية من نوع (حتى انها ليست صحيحة حقا أن أقول الطبقة "ليست جديدة على غرار"!)، وبالتالي فهي عمل الأشياء بشكل صحيح.

نصائح أخرى

وخصائص العمل نوع بيثون، في تجربتي، على ما يرام على الأشياء PyQt4. أنا لا أعرف إذا كانت مدعومة صراحة PyQt4 أم لا أو إذا كان هناك بعض gotchas خفية، ولكن لم أر منهم يسيئون التصرف. وهنا مثال استخدام PyQt 4.4 و 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 هو السماح باستخدام كيو تي في التي ليست هي نفسها كما في بايثون. خصائص كيو تي هي introspectable من داخل الطبقات كيو تي في C ++ (الخصائص التي بيثون الخام ليست)، وتستخدم من قبل كيو تي لأشياء مثل بهم <لأ href = "https://doc.qt.io/qt-4.8/designer-manual هتمل "يختلط =" نوفولو noreferrer "> كيو تي مصمم شكل محرر، و كيو تي الخالق IDE. أنها تسمح الكثير من هذا النوع من التأمل من وقت التشغيل الدولة التي لديك في بيثون ويغيب في C ++. بشكل عام يوفر كيو تي بعض الميزات لغات ديناميكية لC ++، وليس هذا هو المجال الوحيد الذي يوفر باي كيوت أكثر من طريقة واحدة لتفعل الشيء نفسه (تنظر أيضا في الجمل، والمعاجم، وملف I / O وهلم جرا). مع معظم هذه الخيارات النصيحة الرئيسية لدي هو مجرد لاختيار جانب واحد أو الآخر، والعصا معه، فقط لتجنب احتمال بعض التعارض غير سارة. أنا أميل إلى تفضيل نسخة بايثون على نسخة كيو تي لبيثون هو أكثر الأساسية إلى عملي من كيو تي هو. لو كنت ذاهب للنظر في ترقية أي شيء من باي كيوت العودة إلى C ++ كيو تي، مما قد تفضل النسخة كيو تي ميزة على بيثون واحد.

وعلى الأقل في PyQt4.5، والطبقات كيو تي بالتأكيد هي كائنات نمط جديد، كما رأينا من أجل طريقة حلها:

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'>)
scroll top