2010-01-08 13 views
70

मैं पायथन में कुछ वर्ग विरासत करने की कोशिश कर रहा हूं। मैं प्रत्येक वर्ग और विरासत वर्ग को अच्छी डॉकस्ट्रिंग के लिए पसंद करूंगा। इसलिए मैं विरासत में मिला वर्ग के लिए लगता है, मैं इसे करना चाहते हैं:पायथन कक्षा विरासत में इनहेरिट डॉकस्ट्रिंग

  • इनहेरिट आधार वर्ग docstring
  • शायद docstring

के लिए प्रासंगिक अतिरिक्त प्रलेखन संलग्न वहाँ किसी भी है (शायद सुरुचिपूर्ण या पायथनिक) एक वर्ग विरासत की स्थिति में इस तरह के docstring हेरफेर करने का तरीका? एकाधिक विरासत के बारे में कैसे?

उत्तर

32

आप केवल एक ही नहीं हैं! कुछ समय पहले इस बारे में comp.lang.python पर एक चर्चा हुई थी, और एक नुस्खा बनाया गया था। इसे देखें here

""" 
doc_inherit decorator 

Usage: 

class Foo(object): 
    def foo(self): 
     "Frobber" 
     pass 

class Bar(Foo): 
    @doc_inherit 
    def foo(self): 
     pass 

Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber" 
""" 

from functools import wraps 

class DocInherit(object): 
    """ 
    Docstring inheriting method descriptor 

    The class itself is also used as a decorator 
    """ 

    def __init__(self, mthd): 
     self.mthd = mthd 
     self.name = mthd.__name__ 

    def __get__(self, obj, cls): 
     if obj: 
      return self.get_with_inst(obj, cls) 
     else: 
      return self.get_no_inst(cls) 

    def get_with_inst(self, obj, cls): 

     overridden = getattr(super(cls, obj), self.name, None) 

     @wraps(self.mthd, assigned=('__name__','__module__')) 
     def f(*args, **kwargs): 
      return self.mthd(obj, *args, **kwargs) 

     return self.use_parent_doc(f, overridden) 

    def get_no_inst(self, cls): 

     for parent in cls.__mro__[1:]: 
      overridden = getattr(parent, self.name, None) 
      if overridden: break 

     @wraps(self.mthd, assigned=('__name__','__module__')) 
     def f(*args, **kwargs): 
      return self.mthd(*args, **kwargs) 

     return self.use_parent_doc(f, overridden) 

    def use_parent_doc(self, func, source): 
     if source is None: 
      raise NameError, ("Can't find '%s' in parents"%self.name) 
     func.__doc__ = source.__doc__ 
     return func 

doc_inherit = DocInherit 
+0

यह अभिभावक वर्ग 'विधि के डॉक्स्टिंग के उत्तराधिकारी के लिए एक विधि के लिए साफ है। यह मुझे लगता है कि कई मामलों में उपयोगी होगा। मैं पूरी कक्षा के लिए डॉकस्ट्रिंग के बारे में और सोच रहा था, जहां मैं उत्तराधिकारी और संलग्न होना चाहता हूं। –

+0

आह, गोचा। उस स्थिति में, अधिकांश डॉक्टर-पीढ़ी पहले से ही आपके लिए ऐसा करती है। –

23

आप docstrings आसानी से जोड़ सकते हैं:

class Foo(object): 
    """ 
    Foo Class. 
    This class foos around. 
    """ 
    pass 

class Bar(Foo): 
    """ 
    Bar class, children of Foo 
    Use this when you want to Bar around. 
    parent: 
    """ 
    __doc__ += Foo.__doc__ 
    pass 

हालांकि, कि बेकार है। अधिकांश दस्तावेज उत्पादन उपकरण (Sphinx और Epydoc शामिल) पहले से ही विधियों सहित माता-पिता डॉकस्ट्रिंग खींचेंगे। तो आपको कुछ भी करने की ज़रूरत नहीं है।

+9

वास्तव में, अधिकांश दस्तावेज उपकरण ऐसा करते हैं। लेकिन अंतर्निहित सहायता() फ़ंक्शन नहीं करता है। – MarioVilas

+0

@ मारियोविलास: शायद यह एक बग है जिसे रिपोर्ट किया जाना चाहिए? – naught101

3

नहीं विशेष रूप से सुंदर, लेकिन सरल और सीधा:

class X(object): 
    """This class has a method foo().""" 
    def foo(): pass 

class Y(X): 
    __doc__ = X.__doc__ + ' Also bar().' 
    def bar(): pass 
अब

:

>>> print Y.__doc__ 
This class has a method foo(). Also bar(). 
+0

यदि आप 'इनिट डॉकस्ट्रिंग' के लिए भी ऐसा करना चाहते हैं, तो क्या 'वाई' की परिभाषा में ऐसा करने का कोई तरीका है? एकमात्र तरीका यह है कि मैं इसे करने में सक्षम हूं '__init __.__ doc__ = x .__ init __.__ doc__ +" एक और param "' 'y' में '__init__' परिभाषा के बाद' लेकिन यह स्वरूपण के साथ गड़बड़ कर रहा है, जिससे अतिरिक्त अतिरिक्त स्थान – mgilbert

2

एक मिश्रित सूई हैं कि दोनों विरासत में मिला docstring वाक्य रचना और पसंदीदा आदेश रक्षा कर सकते हैं हो सकता है:

class X(object): 
    """This class has a method foo().""" 
    def foo(): pass 

class Y(X): 
    """ Also bar().""" 
    __doc__ = X.__doc__ + __doc__ 
    def bar(): pass 

एलेक्स के समान उत्पादन के साथ:

>>> print Y.__doc__ 
This class has a method foo(). Also bar(). 

पतली बर्फ: docstring के साथ खेल अपने मॉड्यूल python -OO साथ व्यर्थ कर सकते हैं, कुछ उम्मीद:

TypeError: cannot concatenate 'str' and 'NoneType' objects 
-1

मैं custom_inherit लिखा docstring विरासत को संभालने के लिए कुछ सरल, हल्के वजन उपकरण प्रदान करने के लिए।

यह विभिन्न प्रकार के डॉकस्ट्रिंग्स (जैसे नम्पी, Google, और रीस्ट फॉर्मेटेड डॉकस्ट्रिंग) को विलय करने के लिए कुछ अच्छी डिफ़ॉल्ट शैलियों के साथ आता है। आप अपनी शैली को बहुत आसानी से भी प्रदान कर सकते हैं।

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

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