Accessing a Docstring in Python is pretty simple. Just get __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'

I see using wraps as some kind of best practice, when it comes to writing decorators.