user1012451
user1012451

Reputation: 3433

Does functools.wraps have the undecorated reference?

#!/usr/bin/python

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__ + " was called"
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

I want to know if wraps has the undecorated reference to the function f? I don't see it when I tried dir(f)


Modified version

#!/usr/bin/python

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__ + " was called"
        return func(*args, **kwargs)
    with_logging.undecorated = func
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

f.undecorated

No attribute? I was merely following what I used to do with decorator...

Upvotes: 3

Views: 566

Answers (2)

Tobias
Tobias

Reputation: 21

You can access the original function by calling:

f.__wrapped__()

where f is the function that you are decorating

Upvotes: 2

Ned Batchelder
Ned Batchelder

Reputation: 375714

There is a reference to the original f in there, but it's messy to get to.

>>> f
<function f at 0x023F6DF0>
>>> f.func_closure[0].cell_contents
<function f at 0x023F6E30>

The first is the wrapped f, the second is the original f, notice the hex addresses are different.

If you need access to the original f, I suggest you wrap it differently:

def f(x):
   """does some math"""
   return x + x * x
original_f = f
f = logged(f)

Now you have f and original_f, both usable.

Upvotes: 4

Related Questions