如何获取装饰函数的名称?

61 投票
6 回答
50359 浏览
提问于 2025-04-16 11:09

这是我的装饰器:

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

你可能想要使用来自 functoolswraps。看看这个例子。

>>> 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'

撰写回答