سؤال

وهكذا، وأعتقد أن رمز ربما يفسر ما أحاول أن نفعل ما هو أفضل مما أستطيع في الكلمات، حتى هنا المثل:

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