Python inspect.getmembers 与装饰器一起使用时未返回实际函数
我有三个Python函数:
def decorator_function(func)
def wrapper(..)
return func(*args, **kwargs)
return wrapper
def plain_func(...)
@decorator_func
def wrapped_func(....)
它们在一个叫做模块A的地方。
现在我想获取这个模块A里面的所有函数,所以我这样做:
for fname, func in inspect.getmembers(A, inspect.isfunction):
# My code
这里的问题是,func的值并不是我想要的。
我希望得到的是decorator_function、plain_func和wrapped_func,而不是wrapper。
我该怎么做才能确保返回的是wrapped_func,而不是wrapper呢?
2 个回答
6
你可以通过以下方式访问已经装饰过的函数:
wrapped_func.func_closure[0].cell_contents()
举个例子,
def decorator_function(func):
def wrapper(*args, **kwargs):
print('Bar')
return func(*args, **kwargs)
return wrapper
@decorator_function
def wrapped_func():
print('Foo')
wrapped_func.func_closure[0].cell_contents()
会打印出
Foo # Note, `Bar` was not also printed
不过其实,如果你知道自己想要访问那个已经装饰过的函数,那么定义起来会简单很多,
def wrapped_func():
print('Foo')
deco_wrapped_func = decorator_function(wrapped_func)
所以 wrapped_func
就是那个已经装饰过的函数,而 deco_wrapped_func
则是装饰后的版本。
5
如果你只是想让外部能看到原来的函数名字,我觉得你可以这样做:
@functools.wraps
把它作为你的装饰器的装饰器
下面是标准文档中的一个例子:
>>> from functools import wraps
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwds):
... print('Calling decorated function')
... return f(*args, **kwds)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
... print('Called example function')
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'