Sudhan Nadar
Sudhan Nadar

Reputation: 77

accessing function attributes inside decorators

Is it possible to access function attributes inside a decorator? Consider below piece of code.

def deco(a):
    def wrap():
        print(a.status)
        a()
        print(a.status)



    return wrap


@deco
def fun1():
    fun1.status="bar"


fun1.status="foo"
fun1()

I expected the output to be :

foo
bar

But I get the below error:

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    fun1()
  File "D:\python_projects\test_suite\func_attribute.py", line 3, in wrap
    print(a.status)
AttributeError: 'function' object has no attribute 'status'

Is there any way to make this work since

def fun1():
    fun1.status="bar"


fun1.status="foo"

a=fun1

print(a.status)
a()
print(a.status)

Outputs:

foo
bar

As expected.

Upvotes: 3

Views: 933

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121744

Thanks to the decorator, the global name fun1 is bound to the decoration result, so to the nested wrap() function object. Inside wrap() however, a refers to the original, unwrapped function object.

So you have two different function objects, and each can have attributes; they are not the same objects. fun1.status is a different attribute from a.status.

You can access the same object as fun1 in the decorator as wrap:

print(wrap.status)

Demo:

>>> def deco(a):
...     def wrap():
...         print(wrap.status)
...         a()
...         print(wrap.status)
...     return wrap
...
>>> @deco
... def fun1():
...     fun1.status="bar"
...
>>> fun1.status="foo"
>>> fun1()
foo
bar

Upvotes: 1

Related Questions