Because when you wrap a function in a decorator:
@decor
def test:
you get back the function created by the decorator, (living
, in this case) which doesn't have the same docstring, etc. It doesn't "lose" this data, living
never had it!
You can get around this with functools.wraps
:
from functools import wraps
def decor(fun):
@wraps(fun)
def living(*args, **kw):
...
return func
A quick demo to prove the point:
>>> def wrapper(f):
def func(*args):
"""The wrapper func's docstring."""
return f(*args)
return func
>>> @wrapper
def test(x):
"""The test func's docstring."""
return x ** 2
>>> test.__doc__
"The wrapper func's docstring."
versus
>>> from functools import wraps
>>> def wrapper(f):
@wraps(f)
def func(*args):
"""The wrapper func's docstring."""
return f(*args)
return func
>>> @wrapper
def test(x):
"""The test func's docstring."""
return x ** 2
>>> test.__doc__
"The test func's docstring."