Accessing Docstring from decorated functions

Accessing a Docstring in Python is pretty simple. Just call __doc__ on any Python object and it will return the Docstring of the object.

>>> class Foo(object):
...   '''Test Docstring'''
... 
>>> a = Foo()
>>> a.__doc__
'Test Docstring'
>>> Foo.__doc__
'Test Docstring'
>>> def foo():
...     '''Test Docstring'''
... 
>>> foo.__doc__
'Test Docstring'

But what happens if a defined function/method is decorated?

>>> def decorator(cb):
...     def _decorator(*args, **kwargs):
...         return cb(*args, **kwargs)
...     return _decorator
... 
>>> @decorator
... def foo():
...     '''Test Docstring'''
... 
>>> foo.__doc__
>>> repr(foo.__doc__)
'None'

The Docstring of the decorator is returned instead, in this case there is no Docstring, so it’s None. An easy solution is called functools.wraps.

This is a convenience function for invoking partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated) as a function decorator when defining a wrapper function.

wraps preserves some attributes of the original called function/method for example name and Docstring. Just add wraps as decorator to the wrapper function inside your own decorator and calling __doc__ will return the original Docstring again.

>>> from functools import wraps
>>> 
>>> def decorator(cb):
...     @wraps(cb)
...     def _decorator(*args, **kwargs):
...         return cb(*args, **kwargs)
...     return _decorator
... 
>>> @decorator
... def foo():
...     '''Test Docstring'''
... 
>>> foo.__doc__
'Test Docstring'

For me, using wraps, is best practice, when it comes to writing decorators.

2 thoughts on “Accessing Docstring from decorated functions

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>