2009-05-05 14 views
14

तो, मुझे लगता है कि कोड शायद बताते हैं की तुलना में मैं शब्दों में है, इसलिए यहाँ जाता है कर सकते हैं कि मैं क्या बेहतर करने के लिए कोशिश कर रहा हूँ:सार वर्ग + mixin + अजगर में एकाधिक वंशानुक्रम

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 

मैं सारणी/इंटरफ़ेस वर्ग की आवश्यकताओं को पूरा करने के लिए मिश्रित वर्ग प्राप्त करने की कोशिश कर रहा हूं। मैं क्या खो रहा हूँ?

उत्तर

15

विरासत दूसरे तरीके से नहीं होना चाहिए? एमआरओ foo में वर्तमान में bar_for_foo_mixin से पहले आता है, और फिर सही तरीके से शिकायत करता है। class myfoo(bar_for_foo_mixin, foo) के साथ यह काम करना चाहिए।

और मुझे यकीन नहीं है कि आपका वर्ग डिज़ाइन ऐसा करने का सही तरीका है या नहीं। चूंकि आप bar को लागू करने के लिए एक मिश्रण का उपयोग करते हैं, इसलिए यह बेहतर हो सकता है कि foo से प्राप्त न करें और इसे 'foo' वर्ग (यानी foo.register(myfoo)) से पंजीकृत करें। लेकिन यह सिर्फ मेरी आंत महसूस कर रहा है।

पूर्णता के लिए, यहां documentation for ABCs है।

+0

अच्छी कॉल, चाल उत्तराधिकार के आदेश को बदलने करता है । पी.एस. कोड को एक बिंदु को चित्रित करने के लिए सरल बनाया गया था। मेरा असली दुनिया परिदृश्य बहुत सारे जटिल मिश्रणों और कई मायफोस के साथ बहुत जटिल है। – mluebke

0

मुझे लगता है कि (इसी तरह के मामले में परीक्षण) कि baseclasses पीछे काम करता है: इससे पहले कि यह सार एक पाता है

class myfoo(bar_for_foo_mixin, foo): 
    def __init__(self): 
     print "myfoo __init__ called" 
     self.bar() 

तो एमआरओ में() यह बार() की एक ठोस संस्करण मिल जाएगा। कोई विचार नहीं है कि यह वास्तव में पृष्ठभूमि में क्या होता है।

चीयर्स, लार्स

पुनश्च: कोड है कि अजगर में काम किया 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() 
+0

इस उत्तर के लिए धन्यवाद। Py27 में, आपका कोड जो काम करता है वास्तव में वर्ग 'सी' में' do() 'की उपस्थिति को लागू करता है। हालांकि, पी 3 में (मैंने केवल पीई 35 में परीक्षण किया), यह अब मामला नहीं है। कक्षा 'बी' में आप शरीर को 'पास' से बदल सकते हैं, और उदाहरण 'सी' खुशी से बनाया जाएगा। क्या आप जानते हैं कि यह क्यों हो सकता है? –

+0

@cjrh: क्या आपका मतलब बी का शरीर या बीडीओ का शरीर है? यदि पहला, यह वास्तव में अजीब होगा क्योंकि यह एबीसी के उद्देश्य को अस्वीकार कर देगा .. – Lars

+0

बस "पीएस: कोड जो काम किया गया था" के तहत अपना कोड आज़माएं, लेकिन 'बी' से 'कक्षा बी (ऑब्जेक्ट) में बदलें: pass'। आप देखेंगे कि इंस्टेंस 'c' सफलतापूर्वक बनाया गया है। मैंने पाइथन 3.6 पर एक ही परिणाम की कोशिश की। –

संबंधित मुद्दे