MRO في python عند subclassing مع توارث متعددة ، باستخدام PyQt (QMainWindow)

لقد تعرّفت مؤخرًا على TypeError ، لم أفهمها عندما كنت أضع تصنيفًا فرعيًا QMainWindow with PyQt5 .

عند إنشاء فصلين:

class Base (QMainWindow):
    def __init__(self):
        super(Base, self).__init__(None)

class Base2 (object):
    def __init__(self, a, b):
        pass

ثم إنشاء فئة فرعية لكل منهما ، دون أي وسيطات init:

class SubClass( Base, Base2 ):
    def __init__(self):
        Base.__init__(self)
        Base2.__init__(self, 0,0)

أحصل على TypeError عند إنشاء مثيل للفئة الفرعية:

from PyQt5.QtWidgets import QApplication, QMainWindow    
app = QApplication([])
print( SubClass() )

انتاج:

Traceback (most recent call last):
    print(SubClass())
    Base.__init__(self)
    super(Base, self).__init__(None)
TypeError: __init__() missing 2 required positional arguments: 'a' and 'b'

ومع ذلك ، عند تغيير الترتيب لوراثة فئة فرعية (Base2 ، Base): سيتم تشغيل التعليمات البرمجية بشكل جيد.


I read the post in How does Python's super() work with multiple inheritance? and Method Resolution Order but didn't found an answer on this.

(لاحظ أيضًا أن هذا هو نوع محدد من PyQt ، لأنني لم أتمكن من إعادة إظهار المشكلة باستخدام Class-classes بالكامل على object )

هل يمكن لشخص أن يعطي تفسيرا واضحا لهذا behaiviour؟

0
التنفيذ الخاص بك هو عربات التي تجرها الدواب جدا ، لذلك لا يوجد أي خفخ واضح ممكن. من الخطأ دائمًا خلط super مع المكالمات __ init __ - يجب أن تستخدم جميع فئات الأساس super . تحتاج أيضًا إلى إصلاح معالجة التواقيع غير المتطابقة - راجع هذه الإجابة و هذه الإجابة على السؤال الأول الذي ربطته. بمجرد التخلص من هذه المشاكل ، لا يهم ترتيب الطبقات الأساسية.
وأضاف المؤلف ekhumoro, مصدر

1 إجابة

"من الخطأ دائمًا خلط super مع المكالمات __ init __ - يجب أن تستخدم جميع فئات الأساس المحتوى الفائق." - ekhumoro

لم أكن على علم بهذا - شكراً.

علاوة على ذلك ، بناءً على ذلك ، وكذلك على هذه الإجابة و هذه المقالة wordpress من قبل ريموند هتينجر ، يبدو أن أفضل الممارسات بالنسبة لي لاستخدام ** kwargs لتمرير جميع الحجج عبر سلسلة من المكالمات فائقة وتصفية كل جزء جزئيًا لكل خطوة:

class Base (QMainWindow):
    def __init__(self, parent, **kwargs):
        super().__init__(parent, **kwargs)

class Base2 (object):
    def __init__(self, a, b, **kwargs):
        super().__init__(**kwargs)

class SubClass(Base, Base2): # order can be switched now
    def __init__(self):
        super().__init__(a=0, b=0, parent=None)

بهذه الطريقة يصبح MRO غير ذي صلة بهذا المثال.


Research recommendation, for other newbies like me:

0
وأضاف