2010-08-13 9 views
10

में एक विधि को लागू करना चाहिए मान लीजिए कि मैं उप-वर्गों द्वारा लागू किए जाने वाले कुछ तरीकों के साथ अजगर में एक अमूर्त वर्ग बनाना चाहता हूं। (अजगर में)उस सबक्लास को अधिसूचित करने के लिए अपवाद को पाइथन

उदाहरण के लिए

:

class Base(): 
    def f(self): 
     print "Hello." 
     self.g() 
     print "Bye!" 

class A(Base): 
    def g(self): 
     print "I am A" 

class B(Base): 
    def g(self): 
     print "I am B" 

मैं चाहूँगा कि अगर आधार वर्ग instantiated और अपनी च() विधि कहा जाता है, जब ग्राम() कहा जाता है, एक अपवाद को बढ़ाने के लिए, बताए कि एक subclass विधि जी() लागू किया जाना चाहिए था।

यहां क्या करना सामान्य बात है? क्या मुझे NotImplementedError को बढ़ाया जाना चाहिए? या क्या ऐसा करने का एक और विशिष्ट तरीका है?

बहुत बहुत धन्यवाद!
मैनुअल

उत्तर

13

अजगर 2.6 और बेहतर में, आप abc मॉड्यूल Base एक "वास्तव में" सार आधार वर्ग बनाने के लिए उपयोग कर सकते हैं g को ओवरराइड करने के लिए - उपरोक्तों को super का उपयोग g कार्यान्वयन में करने के लिए @ हारून के लक्ष्य को पूरा करते हुए। कुल मिलाकर, पाइथन 2.5 और उससे पहले के दौरान हमारे द्वारा उपयोग किए जाने वाले कार्यों की तुलना में एक बेहतर समाधान!

साइड नोट: ऑब्जेक्ट से आधार उत्तराधिकारी होना अनावश्यक होगा, क्योंकि मेटाक्लास को वैसे भी स्पष्ट रूप से सेट करने की आवश्यकता है।

+0

हा। मुझे बस उस चलने का बुनियादी कार्यान्वयन मिला! मैं इसे अभ्यास के रूप में वैसे भी खत्म कर दूंगा और फिर देख सकता हूं कि मेरा आधिकारिक एक के खिलाफ कैसे खड़ा है। – aaronasterling

+2

बस एक साइड नोड के रूप में: पायथन 3.x में, मेटाक्लास को इस प्रकार परिभाषित किया गया है: कक्षा बेस (मेटाक्लास = abc.ABCMeta): ... –

3

ऐसी कोई विधि बनाएं जो कुछ भी नहीं करे, लेकिन अभी भी इंटरफ़ेस समझाते हुए एक डॉकस्ट्रिंग है। NameError प्राप्त करना भ्रमित है, और NotImplementedError (या उस मामले के लिए कोई अन्य अपवाद) बढ़ाना super का उचित उपयोग तोड़ देगा। - और न कर सकते हैं किसी भी उपवर्ग जो विफल रहता है

import abc 

class Base: 
    __metaclass__ = abc.ABCMeta 
    @abc.abstractmethod 
    def g(self): 
     pass 
    def f(self): # &c 

इस गारंटी देता है कि Base instantiated नहीं किया जा सकता है:

+0

त्रुटि को बढ़ाने से 'सुपर' का उचित उपयोग कैसे होता है? इस मामले में 'सुपर' नहीं बुलाया जाएगा क्योंकि तत्काल उपclass इसे कॉल नहीं करेगा। विरासत श्रृंखला के नीचे सुपर करने के लिए कोई भी कॉल ठीक काम करेगा। – aaronasterling

+0

@Aaronasterling, तत्काल उपclass इसे क्यों नहीं बुलाएगा? यदि आपके पास बेस से प्राप्त होने वाले दो वर्ग हैं और विधि को लागू करते हैं, और एक वर्ग जो दोनों से विरासत में मिलता है, केवल कार्यान्वयन में से एक को बुलाया जाएगा। यदि तत्काल उप-वर्ग दोनों 'सुपर' कहते हैं (जैसा कि वे होना चाहिए), तो दोनों कार्यान्वयन कहा जाएगा। – habnabit

+0

अच्छी कॉल। मैंने अपना जवाब हटा दिया। – aaronasterling

0

पीटर नॉरविग ने अपने पायथन Infrequently Asked Questions सूची में इसके लिए एक समाधान दिया है। मैं इसे यहां पुन: पेश करूंगा। IAQ देखें, यह बहुत उपयोगी है।

## Python 
class MyAbstractClass: 
    def method1(self): abstract 

class MyClass(MyAbstractClass): 
    pass 

def abstract(): 
    import inspect 
    caller = inspect.getouterframes(inspect.currentframe())[1][3] 
    raise NotImplementedError(caller + ' must be implemented in subclass') 
+2

ध्यान दें कि ** ** केवल '' abstract' को ' विधि 1 का शरीर कुछ भी नहीं करता है: आपको ** ** ** कॉल करने की आवश्यकता है। वैसे भी, जबकि पीटर का विचार 2.5 और उससे पहले के लिए फायदेमंद है, 2.6 में और बाद में एबीसी मॉड्यूल मैं अनुशंसा करता हूं: त्रुटि ASAP आता है, जैसे ही एक सार-सारणी कक्षा ** तत्काल ** है, जो हमेशा सहायक होती है फिक्सिंग त्रुटियों। –

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