بيثون الميراث المتعدد: أي __new__ للاتصال؟
-
22-09-2019 - |
سؤال
عندي حصة دراسية Parent
. اريد تحديد أ __new__
ل Parent
لذلك يفعل بعض السحر عند إنشاء مثيل (لسبب ، انظر الحاشية). أريد أيضًا أن ترث دروس الأطفال من هذه الفصول والفصول الأخرى للحصول على ميزات الوالدين. ال Parent
'س __new__
سيعود مثيلًا من فئة فرعية من قواعد فئة الطفل و Parent
صف دراسي.
هذه هي الطريقة التي سيتم بها تعريف فئة الطفل:
class Child(Parent, list):
pass
لكنني الآن لا أعرف ماذا __new__
للاتصال Parent
'س __new__
. إذا اتصلت object.__new__
, ، ما سبق Child
مثال يشكو ذلك list.__new__
يجب أن يسمى. ولكن كيف يمكن Parent
إعلم أن؟ لقد جعلتها تعمل حتى تحلق من خلال كل __bases__
, واتصل كل __new__
داخل try:
منع:
class Parent(object):
def __new__(cls, *args, **kwargs):
# There is a special wrapper function for instantiating instances of children
# classes that passes in a 'bases' argument, which is the __bases__ of the
# Children class.
bases = kwargs.get('bases')
if bases:
cls = type('name', bases + (cls,), kwargs.get('attr', {}))
for base in cls.__mro__:
if base not in (cls, MyMainType):
try:
obj = base.__new__(cls)
break
except TypeError:
pass
return obj
return object.__new__(cls)
لكن هذا يبدو وكأنه اختراق. بالتأكيد ، يجب أن تكون هناك طريقة أفضل للقيام بذلك؟
شكرًا.
- السبب الذي يجعلني أرغب في استخدامه
__new__
لذلك يمكنني إرجاع كائن من الفئة الفرعية التي تحتوي على بعض السمات الديناميكية (السحر__int__
سمات ، إلخ) المعينة للفئة. أنا يمكن أن تفعل هذا في__init__
, ، لكنني لن أتمكن من التعديلself.__class__
في__init__
إذا كان للفئة الجديدة بنية داخلية مختلفة ، وهذا هو الحال هنا بسبب الميراث المتعدد.
المحلول
أعتقد أن هذا سيحصل على ما تريد:
return super(Parent, cls).__new__(cls, *args, **kwargs)
ولن تحتاج إلى bases
حجة الكلمة الرئيسية. ما لم أخطئك وأنت تضع ذلك هناك عن قصد.