如何获取装饰函数的名称?
这是我的装饰器:
def check_domain(func):
def wrapper(domain_id, *args, **kwargs):
domain = get_object_or_None(Domain, id=domain_id)
if not domain:
return None
return func(domain_id, *args, **kwargs)
return wrapper
这是一个被包装的函数:
@check_domain
def collect_data(domain_id, from_date, to_date):
do_stuff(...)
如果我执行 collect_data.__name__
,我得到的是 wrapper
而不是 collect_data
有什么想法吗?
6 个回答
7
除了 functools.wraps
之外,你还可以看看 decorator 这个模块,它是专门用来解决这个问题的。
104
其实不需要用 functools.wraps!你只要用 func.__name__
就可以了。
import time
def timeit(func):
def timed(*args, **kwargs):
ts = time.time()
result = func(*args, **kwargs)
te = time.time()
print('Function', func.__name__, 'time:', round((te -ts)*1000,1), 'ms')
print()
return result
return timed
@timeit
def math_harder():
[x**(x%17)^x%17 for x in range(1,5555)]
math_harder()
@timeit
def sleeper_agent():
time.sleep(1)
sleeper_agent()
输出结果:
Function math_harder time: 8.4 ms
Function sleeper_agent time: 1003.7 ms
54
你可能想要使用来自 functools
的 wraps
。看看这个例子。
>>> from functools import wraps
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwargs):
... print('Calling decorated function')
... return f(*args, **kwargs)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
... print('Called example function')
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'