مجردة من الدرجة + mixin + راثة متعددة في بيثون
-
05-07-2019 - |
سؤال
وهكذا، وأعتقد أن رمز ربما يفسر ما أحاول أن نفعل ما هو أفضل مما أستطيع في الكلمات، حتى هنا المثل:
import abc
class foo(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def bar(self):
pass
class bar_for_foo_mixin(object):
def bar(self):
print "This should satisfy the abstract method requirement"
class myfoo(foo, bar_for_foo_mixin):
def __init__(self):
print "myfoo __init__ called"
self.bar()
obj = myfoo()
والنتيجة:
TypeError: Can't instantiate abstract class myfoo with abstract methods bar
وأنا أحاول الحصول على الدرجة mixin لتلبية متطلبات مجردة / واجهة الطبقة. ما أنا في عداد المفقودين؟
المحلول
ويجب أن لا ميراث يكون العكس؟ في foo
MRO يأتي حاليا من قبل bar_for_foo_mixin
، ثم يشكو بحق. مع class myfoo(bar_for_foo_mixin, foo)
يجب أن يعمل.
وأنا لست متأكدا مما إذا كان تصميم صفك هو الطريق الصحيح لتحقيق ذلك. منذ كنت تستخدم mixin لتنفيذ bar
قد يكون من الأفضل أن لا تنبع من فو ومجرد تسجيله مع الطبقة "فو" (أي foo.register(myfoo)
). ولكن هذا هو مجرد شعوري الداخلي.
لاكتمال، وهنا هو href="http://docs.python.org/library/abc.html" الوثائق rel="noreferrer"> .
نصائح أخرى
وأعتقد (اختبار في قضية مماثلة) الذي عكس baseclasses يعمل:
class myfoo(bar_for_foo_mixin, foo):
def __init__(self):
print "myfoo __init__ called"
self.bar()
وذلك في MRO () فإنه العثور على نسخة ملموسة من شريط () قبل أن يجد واحدة مجردة. أي فكرة إذا كان هذا هو في الواقع ما يحدث في الخلفية بالرغم من ذلك.
وابتهاج، لارس
وPS: التعليمات البرمجية التي عملت في بيثون 2.7 (الثعبان 3 لديه طريقة مختلفة لوضع metaclasses) هو:
class A(object):
__metaclass__ = abc.ABCMeta
@abc.abstractmethod
def do(self):
pass
class B(object):
def do(self):
print "do"
class C(B, A):
pass
c = C()