访问装饰函数的文档?
Access to documentation of a decorated function?
我正在开发一个 API,通过它我将模块的功能列表以及每个功能的文档传递给用户。为了访问我曾经做过的文档:
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
现在我为其中一些函数添加了装饰器,__doc__
returns None
因为装饰器函数没有任何文档。
def decor_func(func):
def wrap(*args, **kwargs):
return func(*args, **kwargs)
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# None
有什么方法可以访问修饰函数的文档吗?
您可以更新 wrap
函数的 __doc__
属性:
def decor_func(func):
def wrap(*args, **kwargs):
return func(*args, **kwargs)
# Set the decorated function `__doc__` attribute
wrap.__doc__ = func.__doc__
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
但是,最好的方法是使用 functools.wraps
,这样您还可以复制其他属性,例如原始名称、模块和注释:
import functools
def decor_func(func):
@functools.wraps(func)
def wrap(*args, **kwargs):
return func(*args, **kwargs)
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
请注意,正如其他人指出的那样,您应该使用 functools.wraps
以便您的包装器“看起来”像它正在包装的函数,并将包装的函数添加到 __wrapped__
属性。但是,请注意,您始终可以内省包装器的闭包以检索对原始函数的引用,因为它是包装器中的自由变量,因此将存储在闭包中:
>>> def decor_func(func):
... def wrap(*args, **kwargs):
... return func(*args, **kwargs)
... return wrap
...
>>> @decor_func
... def foo(*args, **kwargs):
... """
... Foo documentation is here!
... """
... return None
...
>>> foo.__closure__
(<cell at 0x10e69da90: function object at 0x10e83a700>,)
所以,
>>> foo.__closure__[0].cell_contents.__doc__
'\n Foo documentation is here!\n '
但同样,您应该首先使用 functools.wraps
。如果您无法控制装饰器,以上内容可能会有所帮助。
我正在开发一个 API,通过它我将模块的功能列表以及每个功能的文档传递给用户。为了访问我曾经做过的文档:
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
现在我为其中一些函数添加了装饰器,__doc__
returns None
因为装饰器函数没有任何文档。
def decor_func(func):
def wrap(*args, **kwargs):
return func(*args, **kwargs)
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# None
有什么方法可以访问修饰函数的文档吗?
您可以更新 wrap
函数的 __doc__
属性:
def decor_func(func):
def wrap(*args, **kwargs):
return func(*args, **kwargs)
# Set the decorated function `__doc__` attribute
wrap.__doc__ = func.__doc__
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
但是,最好的方法是使用 functools.wraps
,这样您还可以复制其他属性,例如原始名称、模块和注释:
import functools
def decor_func(func):
@functools.wraps(func)
def wrap(*args, **kwargs):
return func(*args, **kwargs)
return wrap
@decor_func
def foo(*args, **kwargs):
"""
Foo documentation is here!
"""
return None
print(foo.__doc__)
# Foo documentation is here!
请注意,正如其他人指出的那样,您应该使用 functools.wraps
以便您的包装器“看起来”像它正在包装的函数,并将包装的函数添加到 __wrapped__
属性。但是,请注意,您始终可以内省包装器的闭包以检索对原始函数的引用,因为它是包装器中的自由变量,因此将存储在闭包中:
>>> def decor_func(func):
... def wrap(*args, **kwargs):
... return func(*args, **kwargs)
... return wrap
...
>>> @decor_func
... def foo(*args, **kwargs):
... """
... Foo documentation is here!
... """
... return None
...
>>> foo.__closure__
(<cell at 0x10e69da90: function object at 0x10e83a700>,)
所以,
>>> foo.__closure__[0].cell_contents.__doc__
'\n Foo documentation is here!\n '
但同样,您应该首先使用 functools.wraps
。如果您无法控制装饰器,以上内容可能会有所帮助。