2013-06-13 11 views
5

अजगर में सबसे अच्छा तरीका है सी # में की तरह आभासी और शुद्ध आभासी कार्यों की नकल करने के क्या है?नकल अजगर (शुद्ध) आभासी सी # जैसे कार्यों

वर्तमान में मैं की तरह एक स्कीमा का उपयोग करें:

class AbstractClass(object): 
    '''Abstract class''' 
    def __init__(self): 
     assert False, 'Class cannot be instantiated' 

    def _virtual_init(self): 
     print 'Base "constructor"' 

    def pure_virtual_function(self): 
     assert False, 'Pure virtual function should be derived' 

    def virtual_function(self): 
     print 'Base: virtual function' 

class Derived1(AbstractClass): 
    '''All functions derived''' 
    def __init__(self): 
     print 'Derived1: constructor' 
     AbstractClass._virtual_init(self) 

    def pure_virtual_function(self): 
     print 'Derived1: pure virtual function' 

    def virtual_function(self): 
     print 'Derived1: virtual function' 

class Derived2(AbstractClass): 
    '''Pure virtual method missing.''' 
    def __init__(self): 
     print 'Derived2: constructor' 
     AbstractClass._virtual_init(self) 

    def virtual_function(self): 
     print 'Derived3: virtual function' 

class Derived3(AbstractClass): 
    '''Virtual method missing (use base class)''' 
    def __init__(self): 
     print 'Derived3: constructor' 
     AbstractClass._virtual_init(self) 

    def pure_virtual_function(self): 
     print 'Derived3: pure virtual function' 


# ab = AbstractClass() # Gives error -> OK 

print 'DERIVED 1'  
dv1 = Derived1() 
dv1.pure_virtual_function() 
dv1.virtual_function() 

print 'DERIVED 2'  
dv2 = Derived2() 
# dv2.pure_virtual_function() # Gives error: Pure virtual function should be derived -> OK 
dv2.virtual_function() 

print 'DERIVED 3'  
dv3 = Derived3() 
# dv3.pure_virtual_function() # Gives error: Pure virtual function should be derived -> OK 
dv3.virtual_function() 

मैं आउटपुट के रूप में मिलती है:

DERIVED 1 
Derived1: constructor 
Base "constructor" 
Derived1: pure virtual function 
Derived1: virtual function 
DERIVED 2 
Derived2: constructor 
Base "constructor" 
Derived3: virtual function 
DERIVED 3 
Derived3: constructor 
Base "constructor" 
Derived3: pure virtual function 
Base: virtual function 

हालांकि मेरे विशिष्ट प्रश्न हैं:

  1. वहाँ परिभाषित करने के लिए एक और अधिक सुरुचिपूर्ण रास्ता नहीं है पायथन (2.7) में एक सार आधार वर्ग? उपरोक्त समाधान केवल रन टाइम पर एक त्रुटि देता है (उदाहरण के लिए पिलिंट के साथ नहीं) पायथन afaik में कोई 'सार' कीवर्ड नहीं है।
  2. क्या पाइथन (2.7) में शुद्ध वर्चुअल विधि को परिभाषित करने का एक और शानदार तरीका है? फिर, उपर्युक्त समाधान केवल रन टाइम पर एक त्रुटि देता है।
  3. क्या पाइथन (2.7) में वर्चुअल विधि को परिभाषित करने का एक और शानदार तरीका है? कोई जांच की आवश्यकता नहीं है, लेकिन Python afaik में 'वर्चुअल' जैसे कोई कीवर्ड नहीं है।

अग्रिम धन्यवाद।

+1

मैं इन डिजाइन पैटर्न के साथ पूरी तरह से परिचित नहीं हूँ ... लेकिन इस कोड को पढ़ने के लिए मुझे 'abc' मॉड्यूल की याद दिलाता है। हो सकता है कि आप वहां एक नज़र डालें और देखें कि क्या वह कार्यक्षमता प्रदान करता है जिसे आप ढूंढ रहे हैं। – mgilson

+1

आप कभी भी रन टाइम त्रुटि से अधिक नहीं प्राप्त करेंगे। वाक्यविन्यास की वैधता के अलावा, बोलने के लिए कोई संकलन समय जांच नहीं है।(हालांकि आप अपने लिए ऐसे चेक करने के लिए * पिलिंट * सिखाने की कोशिश कर सकते हैं।) अभी तक बेहतर है, ** उन सभी स्वच्छ डिजाइन उपकरणों के बारे में ** भूल जाओ। बस कर दो। संगत इंटरफेस के साथ कुछ कक्षाओं को परिभाषित करें, लेकिन इस तरह के इनवेरिएंट को लागू करने के लिए कंप्यूटर को प्राप्त करने की कोशिश किए बिना कोई विरासत, आसपास के उदाहरणों को पास न करें। आप सी #/जावा में सोच रहे हैं। इसका परिणाम पाइथन आउटपुट में भयानक है, जैसे कि पाइथन मानसिकता भयानक सी #/जावा कोड उत्पन्न करेगी। – delnan

+0

आप ऐसा क्यों कर रहे हैं? प्रत्येक भाषा में चीजों को करने का अपना तरीका होता है। आपको अजगर में इसकी आवश्यकता नहीं है। – Lanaru

उत्तर

5

मुझे यकीन है कि वास्तव में क्या मतलब है जब आप अजगर के रूप में, आभासी तरीकों के बारे में पूछने सभी तरीकों आभासी हैं नहीं कर रहा हूँ। और मुझे यह भी यकीन नहीं है कि आप का उपयोग __init__ के बजाय क्यों कर रहे हैं ... क्या आपको बस कुछ विधि खरीदने का नाम बदल रहा है?

अद्यतन: आह, मैं एक विचार मिल गया है। आपने शायद इसे अपने बेस क्लास के तत्कालता को प्रतिबंधित करने के लिए अभी भी प्रारंभिक कार्यक्षमता को बनाए रखा है। यहां जवाब है: चीजों को मजबूर करना पायथनिक नहीं है। बस दस्तावेज करें कि यह वर्ग सार है (और शायद इसे AbstractSmth पर कॉल करें)।

रन-टाइम त्रुटियों के बारे में बोलते हुए। पायथन एक गतिशील भाषा है, इसलिए, ठीक है, यह इस तरह काम करता है। एक सामान्य मुहावरे NotImplementedError__init__ में यह दिखाने के लिए बढ़ा रहा है कि आपकी कक्षा सार है (और यह सार (शुद्ध वर्चुअल) विधियों के लिए भी सच है)। आप abc पर भी एक नज़र डाल सकते हैं जैसा कि आप चाहते हैं: यह अमूर्त वर्गों के तत्कालता को प्रतिबंधित करता है। लेकिन मैं यह भी दृढ़ता से PEP-3119 पढ़ने समझने के लिए सार आधार वर्ग हैं और वे क्या नहीं हैं सुझाव देते हैं। pylint को समझने के लिए है कि अपने वर्ग/विधि सार है

AFAIK, NotImplementedError को ऊपर उठाने के लिए पर्याप्त है।

+0

मैं __init__ के बजाय _virtual_init का उपयोग कर रहा हूं क्योंकि मैं नहीं चाहता कि उपयोगकर्ता सीधे एक अमूर्त वर्ग को तुरंत चालू करें। लेकिन एबीसी मॉड्यूल इस समस्या पर विजय प्राप्त करता है। प्रलेखन लागू करने से कम अच्छा है। और मुझे पता है कि पाइथन एक गतिशील भाषा है, NotImplementedError वास्तव में एक जोर से बेहतर है। पीईपी -3119 लिंक के लिए धन्यवाद। –

0
class AbstractBaseClass(object): 
    def __init__(self): 
     if self.__class__.__name__ == 'AbstractBaseClass': 
      raise NotImplementedError("Can't instantiate AbstractBaseClass") 

class DerivedClass(AbstractBaseClass): 
    def __init__(self): 
     super().__init__() 
     # ... 

यह उदाहरण दिखाता है कि व्युत्पन्न वर्ग (एक अलग __class__.__name__ सदस्य है) instantiated जा सकता है, और AbstractBaseClass द्वारा प्रदान की विशेषताओं के वारिस। लेकिन अगर सारबेसबेस क्लास तुरंत चालू हो जाता है, तो NotImplementedError अपवाद फेंक दिया जाएगा।

+1

अपने उत्तर में कुछ टिप्पणियां जोड़ें – HDJEMAI

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