Inheriting methods but over-riding docstrings
Alf P. Steinbach
alfps at start.no
Sun Jan 17 19:45:17 EST 2010
* Gabriel Genellina:
> En Sat, 16 Jan 2010 14:55:11 -0300, Steven D'Aprano
> <steve at 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
More information about the Python-list
mailing list