2013-02-20 34 views
13

मैं एक सी # पृष्ठभूमि से आया हूं जहां भाषा ने "डेवलपर की रक्षा" सुविधाओं में कुछ बनाया है। मैं समझता हूं कि पाइथन "हम सभी वयस्क हैं" दृष्टिकोण लेते हैं और डेवलपर को विचारपूर्वक और ध्यान से कोड करने की जिम्मेदारी देते हैं।पायथन सार कक्षाएं - तत्कालता को हतोत्साहित करने के लिए कैसे?

यह कहा गया है कि पाइथन निजी आवृत्ति चर के लिए अग्रणी अंडरस्कोर जैसे सम्मेलनों का सुझाव देता है। मेरा सवाल है, क्या कक्षा को केवल डॉकस्ट्रिंग में निर्दिष्ट करने के अलावा अन्य को सार के रूप में चिह्नित करने के लिए एक विशेष सम्मेलन है? मैंने विशेष रूप से पाइथन शैली मार्गदर्शिका में कुछ भी नहीं देखा है जो सार वर्गों के लिए सम्मेलन नामकरण का उल्लेख करता है।

मैं अब तक 3 विकल्प के बारे में सोच सकते हैं, लेकिन मुझे यकीन है कि अगर वे अच्छे विचार कर रहे हैं नहीं कर रहा हूँ:

  1. श्रेणी से ऊपर docstring में यह निर्दिष्ट करें (अनदेखी की जा सकती है)
  2. एक अग्रणी उपयोग वर्ग के नाम (यकीन नहीं अगर यह सार्वभौमिक समझा जाता है) में रेखांकित
  3. सार वर्ग कि एक त्रुटि को जन्म देती है पर एक def __init__(self): विधि बनाएँ (यकीन है कि, अगर यह नकारात्मक रूप से प्रभावित विरासत नहीं जैसा कि आप किसी आधार निर्माता कॉल करना चाहते हैं)

इनमें से एक अच्छा विकल्प है या क्या कोई बेहतर है? मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि अन्य डेवलपर्स जानते हैं कि यह सार है और इसलिए यदि वे इसे तुरंत चालू करने का प्रयास करते हैं तो उन्हें किसी भी अजीब व्यवहार की ज़िम्मेदारी स्वीकार करनी चाहिए।

+0

यदि आप 'सुपर .__ init__' को कॉल करने वाले किसी व्यक्ति के बारे में चिंतित हैं, या इसे कुछ करना चाहते हैं लेकिन * सीधे * तत्काल नहीं है, तो आपके पास 'बेस .__ init__' में ऐसा कुछ हो सकता है:' यदि टाइप (स्वयं) आधार है: NotImplementedError बढ़ाएं ('बेस .__ init __(): अमूर्त वर्ग') ' –

उत्तर

21

यदि आप पायथन 2.6 या उच्चतर का उपयोग कर रहे हैं, तो आप मानक पुस्तकालय से Abstract Base Class मॉड्यूल का उपयोग कर सकते हैं यदि आप अमूर्तता को लागू करना चाहते हैं।यहाँ एक उदाहरण है:

from abc import ABCMeta, abstractmethod 

class SomeAbstractClass(object): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def this_method_must_be_overridden(self): 
     return "But it can have an implementation (callable via super)." 

class ConcreteSubclass(SomeAbstractClass): 
    def this_method_must_be_overridden(self): 
     s = super(ConcreteSubclass, self).this_method_must_be_overridden() 
     return s.replace("can", "does").replace(" (callable via super)", "") 

आउटपुट:

>>> a = SomeAbstractClass() 
Traceback (most recent call last): 
    File "<pyshell#13>", line 1, in <module> 
    a = SomeAbstractClass() 
TypeError: Can't instantiate abstract class SomeAbstractClass with abstract 
methods this_method_must_be_overridden 
>>> c = ConcreteSubclass() 
>>> c.this_method_must_be_overridden() 
'But it does have an implementation.' 
5

आपकी आखिरी वाक्य के आधार पर, मैं जवाब देता हूं कि "बस इसे दस्तावेज करें"। कोई भी जो इस तरह से कक्षा का उपयोग करता है कि दस्तावेज़ीकरण कहता है कि किसी भी अजीब व्यवहार की ज़िम्मेदारी स्वीकार नहीं करनी चाहिए।

पायथन में abstract base class तंत्र है, लेकिन अगर आपका एकमात्र लक्ष्य तत्कालता को हतोत्साहित करना है तो इसका उपयोग करने का कोई कारण नहीं दिखता है।

+0

+1 क्योंकि मुझे लगता है कि यह आमतौर पर जाने का सही तरीका है। हालांकि मुझे @ ब्लैकनघट का जवाब देना पड़ा क्योंकि वह आधार पर कार्यान्वयन के बारे में थोड़ा और स्पष्ट था जिसे केवल उप प्रकार से ही बुलाया जा सकता है। यह विशेष रूप से रचनाकारों पर उपयोगी हो सकता है जहां आप आधार '__init__' विधि पर कुछ साझा तर्क चाहते हैं। –

2

अपनी 'सार' कक्षा बनाएं और return NotImplemented या raise NotImplementedError का उपयोग अमूर्त तरीकों से करें।

यह कक्षा का उपयोग करने वाले लोगों को नहीं रोकेगा, लेकिन वास्तविक बतख-टाइपिंग फैशन में यह केवल एक मुद्दा बन जाएगा जब आप अमूर्त विधि का उपयोग करने का प्रयास करेंगे।

+6

'वापसी न करें' के साथ बहुत सावधान रहें। यह एक बहुत ही विशिष्ट इरादा उपयोग मामले है। सी.एफ़ http://stackoverflow.com/questions/1062096/python-notimplemented-constant और दस्तावेज़ों में ''लागू नहीं किया गया' विवरण] (http://docs.python.org/2/library/constants.html#NotImplemented)। आम तौर पर आप 'लागू नहीं किया गया इरर() 'बढ़ाना चाहते हैं। –

2

मैं बस अपने सार वर्गों को उपसर्ग 'सार' के साथ नामित करता हूं। जैसे सारडिडेविस, सारपैकेट, आदि

यह जितना आसान और बिंदु है उतना ही है। यदि अन्य आगे बढ़ने का विकल्प चुनते हैं और तत्काल और/या 'सार' शब्द से शुरू होने वाली कक्षा का उपयोग करते हैं, तो वे या तो जानते हैं कि वे क्या कर रहे हैं या फिर भी उनके लिए कोई उम्मीद नहीं थी।

यह इस प्रकार का नामकरण भी, अपने आप के लिए एक अनुस्मारक गहरी अमूर्त पदानुक्रम के साथ पागल हो जाना करने के लिए नहीं के रूप में कार्य करता है क्योंकि कक्षाओं की एक पूरी बहुत कुछ के मोर्चे पर 'सार' डाल भी बेवकूफ लगता है।

+1

एक और आम पायथन सम्मेलन "आधार" है। "बेसएक्सवाईजेड" वर्ग आमतौर पर तत्काल होने का इरादा नहीं रखते हैं। (दो मामले जो तुरंत मेरे दिमाग में वसंत करते हैं, जहां "बेस" का उपयोग किया जाता है, जहां डीजेगो मॉडल और पायथन का अंतर्निहित HTTP सर्वर होता है।) –

+0

@ क्रिस मॉर्गन और 'बेसस्ट्रिंग' - एक 'टाइप एरर फेंकता है: बेसस्ट्रिंग प्रकार को तत्काल नहीं किया जा सकता है' –

+0

@ ChrisMorgan यहां कुछ संबंधित चर्चा: http://mail.python.org/pipermail/python-dev/2003-November/039916.html –

0

चीजों को लागू करने के लिए संभव है, बल्कि unpythonic है। जब मैं कई वर्षों के सी ++ प्रोग्रामिंग के बाद पाइथन आया, तो मैंने ऐसा करने की भी कोशिश की, मुझे लगता है कि ज्यादातर लोग ऐसा करने की कोशिश करते हैं यदि उनके पास अधिक शास्त्रीय भाषाओं में अनुभव हो। Metaclasses नौकरी करेगा, लेकिन फिर भी पाइथन संकलन समय पर बहुत कम चीजें जांचता है। आपका चेक अभी भी रनटाइम पर किया जाएगा। तो, क्या एक निश्चित वर्ग बनाने में असमर्थता वास्तव में उपयोगी है अगर केवल रनटाइम पर खोज की जाती है? सी ++ में (और सी # में भी) आप एक अमूर्त वर्ग बनाने के कोड को संकलित भी नहीं कर सकते हैं, और यह पूरी बात है - जितनी जल्दी हो सके समस्या को खोजने के लिए। यदि आपके पास अमूर्त विधियां हैं, तो NotImplementedError अपवाद बढ़ाना काफी पर्याप्त लगता है। एनबी: बढ़ाना, एक त्रुटि कोड वापस नहीं! पाइथन त्रुटियों में आमतौर पर चुप नहीं होना चाहिए जब तक कि स्पष्ट रूप से चुप नहीं हो जाते। दस्तावेजीकरण। एक वर्ग का नाम इस तरह से कहता है कि यह सार है। बस इतना ही।

पाइथन कोड की गुणवत्ता अधिकतर विधियों के साथ सुनिश्चित की जाती है जो उन्नत संकलन-समय प्रकार की जांच वाले भाषाओं में उपयोग किए जाने वाले लोगों से काफी अलग हैं। व्यक्तिगत रूप से मैं मानता हूं कि गतिशील रूप से टाइप किए गए lngauges और दूसरों के बीच सबसे गंभीर अंतर है। यूनिट परीक्षण, कवरेज विश्लेषण इत्यादि। नतीजतन, कोड का डिज़ाइन काफी अलग है: चीजों को लागू करने के लिए सब कुछ नहीं किया जाता है, लेकिन उन्हें यथासंभव आसान परीक्षण करने के लिए किया जाता है।

+0

यदि यह अवांछित था, तो मुझे लगता है कि हम 'abc' लाइब्रेरी नहीं देख रहे होंगे पायथन 2.6 के साथ पेश किया :) –