* Gabriel Genellina:
En Sat, 16 Jan 2010 14:55:11 -0300, Steven D'Aprano <st...@remove-this-cybersource.com.au> escribió:

I have a series of subclasses that inherit methods from a base class, but
I'd like them to have their own individual docstrings. The obvious
solution (other than copy-and-paste) is this:


class Base(object):
    colour = "Blue"
    def parrot(self):
        """docstring for Base"""
        return "Norwegian %s" % self.colour


class SubClass(Base):
    colour = "Red"
    def parrot(self):
        """docstring for Subclass"""
        return super(Subclass, self).parrot()


but that adds an awful lot of boilerplate to my subclasses. Are there any
other good solutions to this problem?

Methods don't have docstrings; functions do. So one has to "clone" the function to set a new docstring.

<code>
def copy_function(fn, docstring):
    fn = getattr(fn, "im_func", fn) # accomodate unbound methods in 2.x
    function_type = type(lambda:0)
newfn = function_type(fn.__code__, fn.__globals__, fn.__name__, fn.__defaults__, fn.__closure__)
    newfn.__doc__ = docstring
    return newfn

class Base(object):
    colour = "Blue"
    def parrot(self):
        """docstring for Base"""
        return "Norwegian %s" % self.colour

class SubClass(Base):
    colour = "Red"
    parrot = copy_function(Base.parrot, "docstring for Subclass")

</code>

py> x = Base()
py> print(x.parrot())
Norwegian Blue
py> print x.parrot.__doc__
docstring for Base
py> y = SubClass()
py> print(y.parrot())
Norwegian Red
py> print y.parrot.__doc__
docstring for Subclass

Since Steven says he has a series of subclasses, perhaps wrapping those function calls in a decorator?


<code>
def copy_function(fn, docstring):
    # Gabriel Genellina's copy_function
    fn = getattr(fn, "im_func", fn) # accomodate unbound methods in 2.x
    function_type = type(lambda:0)
newfn = function_type(fn.__code__, fn.__globals__, fn.__name__, fn.__defaults__, fn.__closure__)
    newfn.__doc__ = docstring
    return newfn

def docstrings(**kwargs):
    def with_altered_docstrings(cls, kwargs=kwargs):
        for kwarg in kwargs.items():
            func_name = kwarg[0]
            docstring = kwarg[1]
            original_func = getattr(cls, func_name)
            new_func = copy_function(getattr(cls, func_name), docstring)
            setattr(cls, func_name, new_func)
            return cls
    return with_altered_docstrings


class Base(object):
    colour = "Blue"
    def parrot(self):
        """docstring for Base"""
        return "Norwegian %s" % self.colour

@docstrings( parrot = "docstring for Subclass" )
class SubClass(Base):
    colour = "Red"
</code>


This is my first decorator ever so it might be Incorect and nonIdiomatic...

Also, neither 'copy_function' nor 'docstrings' seem to work with slots.


Steven: on a personal note, earlier when I saw you (I think it was you) using the "Norwegian Parrot" example I thought it referred to me because that was the only sense I could make of it, it followed right after some discussion we had. Thus my impression of you or or responses in this group was colored by a false interpretation. But, checking, which is often a good idea!, and *which I should have done then*, as far as I can see the term was first used in this group in April 2001, <url: http://groups.google.com/group/comp.lang.python/browse_thread/thread/12a125ceddd401e2/c021547a1dc14a41>.

It's still a mystery to me what it refers to, though... :-)


Cheers & hth.,

- Alf
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to