python - 如何通过类装饰器通过 `functools.wraps`访问装饰类的属性

标签 python decorator python-decorators

我正在关注David Beazley's Python Cookbook的类装饰器配方,这似乎更合适,因为它使用 functools.wraps 为装饰器提供更好的组织和属性。

但是,我不太清楚如何(或是否)从装饰器本身内部访问实例的属性。这是代码片段:

import time
import types
from functools import wraps

class TimeDecorator():

    def __init__(self, func):
        wraps(func)(self)

    def __call__(self, *args, **kwargs):
        tic = time.time()
        func_return = self.__wrapped__(*args, **kwargs)
        tac = time.time()
        total_time = round((tac - tic) / 60, 2)
        print(f'Operation Time: {total_time} min.')
        # print(self.__wrapped__.test_attr) # going to give an error...
        return func_return

    def __get__(self, instance, cls):
        if instance is None:
            return self
        else:
            return types.MethodType(self, instance)


class A():

    def __init__(self):
        self.test_attr = 0

    @TimeDecorator
    def do_something(self):
        time.sleep(1) # example of stuff only...

我尝试通过 self.__wrapped__.test_attrself.__wrapped__.__self__.test_attr 从装饰器的 __call__ 访问实例,但他们都告诉我:

AttributeError: 'function' object has no attribute 'test_attr'

那么在这种情况下我如何才能访问装饰类的属性呢?或者我必须使用另一种方式来构建我的装饰器?

最佳答案

您正在实例方法上应用装饰器,因此该装饰方法绑定(bind)的实例将作为第一个参数 self 传入,您可以在其中找到该实例属性,因此您只需从参数中提取 self 即可,在下面的示例中名为 wrapped_self:

def __call__(self, wrapped_self, *args, **kwargs):
    tic = time.time()
    func_return = self.__wrapped__(wrapped_self, *args, **kwargs)
    tac = time.time()
    total_time = round((tac - tic) / 60, 2)
    print(f'Operation Time: {total_time} min.')
    print(wrapped_self.test_attr)
    return func_return

关于python - 如何通过类装饰器通过 `functools.wraps`访问装饰类的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57808886/

相关文章:

python - 在 Ubuntu 18.04 上将 python 包安装到 salome_meca 的 python 发行版

python - 类方法装饰器的一些问题

Python inspect.getmembers 在与装饰器一起使用时不返回实际函数

python - 简单非本地绑定(bind)的 NameError

python - C# 和 Python UDP 示例之间的区别

php - 解析大型 XML 数据

python - 新维度中的 "stacking"数组?

typescript - 是否可以为方法装饰器选项提供类型安全

python - 陷阱异常,再试一次Python中的装饰器

python - 如何防止使用装饰器在views.py 中处理表单时出现重复代码?