Доступ к атрибутам функций внутри декораторов

Можно ли получить доступ к атрибутам функции внутри декоратора? Рассмотрим ниже кусок кода.

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
Другие вопросы по тегам