Доступ к атрибутам функций внутри декораторов
Можно ли получить доступ к атрибутам функции внутри декоратора? Рассмотрим ниже кусок кода.
def deco(a):
def wrap():
print(a.status)
a()
print(a.status)
return wrap
@deco
def fun1():
fun1.status="bar"
fun1.status="foo"
fun1()
Я ожидал, что результат будет:
foo
bar
Но я получаю следующую ошибку:
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'
Есть ли способ сделать эту работу с
def fun1():
fun1.status="bar"
fun1.status="foo"
a=fun1
print(a.status)
a()
print(a.status)
Выходы:
foo
bar
Как и ожидалось.
1 ответ
Решение
Благодаря декоратору, глобальное имя fun1
привязан к результату оформления, поэтому к вложенному wrap()
функциональный объект. внутри wrap()
тем не мение, a
ссылается на оригинальный, развернутый функциональный объект.
Таким образом, у вас есть два разных функциональных объекта, и каждый может иметь атрибуты; они не одинаковые объекты. fun1.status
это другой атрибут от a.status
,
Вы можете получить доступ к тому же объекту, что и fun1
в декораторе как wrap
:
print(wrap.status)
Демо-версия:
>>> 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