2010-06-16 18 views
72

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

class Albatross(object): 
    """A bird with a flight speed exceeding that of an unladen swallow. 

    Attributes: 
    """ 

    flight_speed = 691 
    __doc__ += """ 
     flight_speed (691) 
      The maximum speed that such a bird can attain. 
    """ 

    nesting_grounds = "Raymond Luxury-Yacht" 
    __doc__ += """ 
     nesting_grounds ("Raymond Luxury-Yacht") 
      The locale where these birds congregate to reproduce. 
    """ 

    def __init__(self, **keyargs): 
     """Initialize the Albatross from the keyword arguments.""" 
     self.__dict__.update(keyargs) 

इस वर्ग के प्रारंभिक मानक docstring अनुभाग docstring, साथ ही लाइनों में परिणाम होगा __doc__ को संवर्धित काम के माध्यम से प्रत्येक विशेषता के लिए कहा: वर्तमान में मैं बात की इस तरह कर रहा हूँ।

हालांकि यह शैली docstring style guidelines में स्पष्ट रूप से वर्जित नहीं लगती है, इसे भी एक विकल्प के रूप में नहीं बताया गया है। यहां का लाभ यह है कि यह अपनी परिभाषाओं के साथ विशेषताओं को दस्तावेज करने का एक तरीका प्रदान करता है, जबकि अभी भी एक प्रस्तुत करने योग्य वर्ग डॉकस्ट्रिंग बना रहा है, और डॉकस्ट्रिंग से जानकारी दोहराते हुए टिप्पणियां लिखने से परहेज करता है। मैं अभी भी परेशान हूं कि मुझे वास्तव में गुणों को दो बार लिखना है; मैं कम से कम डिफ़ॉल्ट मानों के डुप्लिकेशंस से बचने के लिए डॉकस्ट्रिंग में मानों के स्ट्रिंग प्रस्तुतियों का उपयोग करने पर विचार कर रहा हूं।

क्या यह इस समुदाय के सम्मेलनों का एक गंभीर उल्लंघन है? क्या यह सही है? क्या कोई बेहतर तरीका है? उदाहरण के लिए, गुणों के लिए मूल्यों और डॉकस्ट्रिंग वाले शब्दकोश बनाना संभव है और फिर कक्षा __dict__ में सामग्री जोड़ें और कक्षा घोषणा के अंत की ओर डॉकस्ट्रिंग; यह विशेषता नाम और मानों को दो बार टाइप करने की आवश्यकता को कम करेगा। संपादित करें: यह आखिरी विचार है, मुझे लगता है कि वास्तव में संभव नहीं है, कम से कम गति से डेटा से पूरी कक्षा का निर्माण नहीं किया जाता है, जो वास्तव में एक बुरा विचार लगता है जब तक कि ऐसा करने का कोई अन्य कारण न हो।

मैं अजगर के लिए काफी नया हूं और अभी भी कोडिंग शैली के विवरण का काम कर रहा हूं, इसलिए असंबद्ध आलोचनाओं का भी स्वागत है।

+0

यदि आप Django मॉडल विशेषताओं को दस्तावेज करने का कोई तरीका ढूंढ रहे हैं, तो यह सहायक हो सकता है: https://djangosnippets.org/snippets/2533/ –

+0

डुप्लिकेट [पायथन में फ़ील्ड और गुणों को कैसे दस्तावेज़ित करें?] (Http : //stackoverflow.com/questions/6060813/how-to-document-fields-and-properties-in-python) जिसमें एक अलग समाधान है। – bufh

उत्तर

50

भ्रम से बचने के लिए: शब्द संपत्ति में पाइथन में specific meaning है। आप किस बारे में बात कर रहे हैं वह है जिसे हम class attributes कहते हैं। चूंकि वे हमेशा अपनी कक्षा के माध्यम से कार्य करते हैं, मुझे लगता है कि उन्हें कक्षा 'दस्तावेज़ स्ट्रिंग के भीतर दस्तावेज़ित करना समझ में आता है। कुछ ऐसा:

class Albatross(object): 
    """A bird with a flight speed exceeding that of an unladen swallow. 

    Attributes: 
     flight_speed  The maximum speed that such a bird can attain. 
     nesting_grounds The locale where these birds congregate to reproduce. 
    """ 
    flight_speed = 691 
    nesting_grounds = "Throatwarbler Man Grove" 

मुझे लगता है कि आपके उदाहरण में दृष्टिकोण की तुलना में आंखों पर बहुत आसान है। यदि मैं वास्तव में दस्तावेज़ स्ट्रिंग में विशेषता मानों की प्रतिलिपि चाहता हूं, तो मैं उन्हें प्रत्येक विशेषता के विवरण के नीचे या नीचे रखूंगा।

संपादित करें:

ध्यान रखें कि अजगर में, डॉक तार वस्तुओं वे दस्तावेज़, न केवल स्रोत कोड टिप्पणियों का वास्तविक सदस्य हैं। चूंकि क्लास एट्रिब्यूट वेरिएबल्स ऑब्जेक्ट्स के संदर्भ में नहीं हैं लेकिन ऑब्जेक्ट्स के संदर्भ हैं, उनके पास अपने स्वयं के डॉक्टर स्ट्रिंग रखने का कोई तरीका नहीं है। मुझे लगता है कि आप संदर्भों पर डॉक्टर स्ट्रिंग के लिए केस बना सकते हैं, शायद "वास्तव में यहां क्या है" के बजाय "यहां क्या जाना चाहिए" का वर्णन करने के लिए, लेकिन मुझे कक्षा वर्ग स्ट्रिंग में ऐसा करने में काफी आसान लगता है।

+0

मुझे लगता है कि ज्यादातर मामलों में यह ठीक है, क्योंकि गुण-शब्दावली सुधार के लिए धन्यवाद- संक्षेप में पर्याप्त रूप से घोषित किया गया है कि उन्हें वर्ग घोषणा की शुरुआत में ही समूहीकृत किया जा सकता है, बिना किसी पढ़ने के लिए इसे पीछे छोड़ने के लिए अव्यवहारिक बना दिया जा सकता है दोनों प्रलेखन और डिफ़ॉल्ट मान} या {दस्तावेज़ीकरण और/या डिफ़ॉल्ट मान दोनों उदाहरणों को अद्यतन करें}। – intuited

+1

यह भी ध्यान दें कि मेरा उदाहरण क्लास के डॉकस्ट्रिंग में विशेषताओं के लिए प्रलेखन का कारण बन जाएगा। मैं वास्तव में दस्तावेजों को विशेषताओं के दस्तावेज़ों में स्वयं रखना पसंद करूंगा, लेकिन यह अधिकांश बिल्टिन प्रकारों के लिए काम नहीं करता है। – intuited

+0

हां, मेरा प्रारंभिक विचार सिर्फ घोषित करना था उदा। 'flight_speed = 691; flight_speed .__ doc__ = "blah blah" '। मुझे लगता है कि आप अपने ** संपादन ** में उल्लेख कर रहे हैं। दुर्भाग्यवश, यह (अधिकांश?) बिल्टिन प्रकारों (जैसे उस उदाहरण में 'int') की तत्कालताओं के लिए काम नहीं करता है।यह उपयोगकर्ता परिभाषित प्रकारों के तत्काल के लिए काम करता है। =========== वास्तव में एक पीईपी था (क्षमा करें, संख्या भूल जाओ) जिसने वर्ग/मॉड्यूल विशेषताओं के लिए डॉकस्ट्रिंग जोड़ने का प्रस्ताव दिया था, लेकिन इसे अस्वीकार कर दिया गया क्योंकि वे इसे स्पष्ट करने के लिए एक तरीका नहीं समझ पाए क्या डॉकस्ट्रिंग पिछले या निम्नलिखित विशेषताओं के लिए थे। – intuited

18

आप PEP257 का हवाला देते हैं: Docstring कन्वेंशनों, खंड What is a docstring में यह कहा गया है:

स्ट्रिंग अजगर कोड में कहीं और होने वाली शाब्दिक भी प्रलेखन के रूप में कार्य कर सकते हैं। वे पायथन बाइटकोड संकलक द्वारा मान्यता प्राप्त नहीं हैं और रनटाइम ऑब्जेक्ट विशेषताओं के रूप में उपलब्ध नहीं हैं (यानी।__doc__ को असाइन नहीं किया गया है), लेकिन सॉफ़्टवेयर टूल्स द्वारा दो प्रकार के अतिरिक्त डॉकस्ट्रिंग निकाले जा सकते हैं:

मॉड्यूल, कक्षा या __init__ विधि के शीर्ष स्तर पर एक साधारण असाइनमेंट के तुरंत बाद स्ट्रिंग अक्षरलेखक "विशेषता डॉकस्ट्रिंग" कहा जाता है ।

और पीईपी 258 में अधिक जानकारी में यह समझाया गया है: विशेषता डॉकस्ट्रिंग्स। जैसा कि ऊपर बताता है ʇsәɹoɈ। एक विशेषता ऐसी ऑब्जेक्ट नहीं है जो __doc__ का मालिक हो ताकि वे help() या pydoc में दिखाई न दें। ये दस्तावेज़ों का उपयोग केवल जेनरेट किए गए दस्तावेज़ों के लिए किया जा सकता है।

लेकिन वर्तमान में कुछ टूल उनका उपयोग करते हैं।

बड़े Epydoc do use them और स्फिंक्स v0.6 में यह शुरू की है और v1.1 में इसे बढ़ाया। स्फिंक्स एक असाइनमेंट से पहले या किसी असाइनमेंट के बाद एक विशेष टिप्पणी में लाइन पर डॉकस्ट्रिंग का उपयोग कर सकते हैं।

directive autoattribute in the Sphinx Manual और विशेषता दस्तावेज़ों के उदाहरण देखें।

+0

जेडीआई-विम प्लगइन विशेषता दस्तावेज़ों को भी पहचानता है। –

+1

मुझे नहीं पता कि यह कब पेश किया गया था, लेकिन स्फिंक्स 1.2.2 में जेनरेट किए गए दस्तावेज़ों में विशेषता डॉकस्ट्रिंग शामिल है। – jochen

+1

धन्यवाद @ jochen, मैं अपना जवाब अपडेट करता हूं। – marcz

7

आप इस प्रभाव के लिए गुणों का दुरुपयोग कर सकते हैं। गुणों में एक गेटर, एक सेटर, एक डिलीटर, और एक डॉकस्ट्रिंग होता है। भोलेपन से, यह बहुत वर्बोज़ मिलेगा:

class C: 
    def __init__(self): 
     self._x = None 

    @property 
    def x(self): 
     """Docstring goes here.""" 
     return self._x 

    @x.setter 
    def x(self, value): 
     self._x = value 

    @x.deleter 
    def x(self): 
     del self._x 

तो फिर तुम एक docstring Cx से संबंधित होगा:

In [24]: print(C.x.__doc__) 
Docstring goes here. 

कई विशेषताओं के लिए ऐसा करने के लिए बोझिल है, लेकिन आप एक सहायक समारोह myprop कल्पना कर सकता:

def myprop(x, doc): 
    def getx(self): 
     return getattr(self, '_' + x) 

    def setx(self, val): 
     setattr(self, '_' + x, val) 

    def delx(self): 
     delattr(self, '_' + x) 

    return property(getx, setx, delx, doc) 

class C: 
    a = myprop("a", "Hi, I'm A!") 
    b = myprop("b", "Hi, I'm B!") 

In [44]: c = C() 

In [46]: c.b = 42 

In [47]: c.b 
Out[47]: 42 

In [49]: print(C.b.__doc__) 
Hi, I'm B! 

इसके बाद, भागीदार अजगर बुला help दे देंगे:

Help on class C in module __main__: 

class C 
| Data descriptors defined here: 
| 
| a 
|  Hi, I'm A! 
| 
| b 
|  Hi, I'm B! 

which I think should be pretty much what you're after. 

संपादित: मैं अब पता है कि हम शायद क्योंकि आंतरिक नाम कोई फर्क नहीं पड़ता, बिल्कुल myprop को पहला तर्क पारित करने के लिए जरूरत के लिए बच सकते हैं। यदि myprop की अगली कॉल किसी अन्य के साथ संवाद कर सकती हैं, तो यह स्वचालित रूप से एक लंबे और असंभव आंतरिक विशेषता नाम पर निर्णय ले सकती है। मुझे यकीन है कि इसे लागू करने के तरीके हैं, लेकिन मुझे यकीन नहीं है कि वे इसके लायक हैं या नहीं।