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.
Thanks, I don’t use yet, but worth memorized
Nice tip.
I’d wondered hiw to get around that problem. But I haven’t taken the time to figure it out.
So thanks for posting.