Get the name of a decorated function?

PythonDjangoDecorator

Python Problem Overview


here is my decorator:

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

Here is a wrapped up function:

@check_domain
def collect_data(domain_id, from_date, to_date):
    do_stuff(...)

If I do collect_data.__name__ I get wrapper instead of collect_data

Any ideas?

Python Solutions


Solution 1 - Python

functools.wraps is not needed! Just use 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()

Outputs:

Function math_harder time: 8.4 ms
Function sleeper_agent time: 1003.7 ms

Solution 2 - Python

You may want to use wraps from functools. See the example

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

Solution 3 - Python

In addition to functools.wraps, you can check out the decorator module which was designed to help with this problem.

Solution 4 - Python

Solution 5 - Python

Check out functools.wraps. Requires python 2.5 or higher though, if that's an issue.

Solution 6 - Python

For anyone who needs to access the decorated function name when there are multiple decorators, like this:

@decorator1
@decorator2
@decorator3
def decorated_func(stuff):
    return stuff

the functools.wraps mentioned above solves that.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRadiantHexView Question on Stackoverflow
Solution 1 - PythonZach EstelaView Answer on Stackoverflow
Solution 2 - PythonTommaso BarbugliView Answer on Stackoverflow
Solution 3 - PythontkerwinView Answer on Stackoverflow
Solution 4 - PythonTomasz ZielińskiView Answer on Stackoverflow
Solution 5 - PythonmeshantzView Answer on Stackoverflow
Solution 6 - PythonZevgonView Answer on Stackoverflow