Inherit docstrings in Python class inheritance

后端 未结 5 2502
难免孤独
难免孤独 2020-12-01 02:25

I\'m trying to do some class inheritance in Python. I\'d like each class and inherited class to have good docstrings. So I think for the inherited class, I\'d like it to:

5条回答
  •  北荒
    北荒 (楼主)
    2020-12-01 03:02

    You're not the only one! There was a discussion on comp.lang.python about this a while ago, and a recipe was created. Check it out 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 
    

提交回复
热议问题