python - 实例化后装饰类及其成员

标签 python decorator

我正在尝试创建一些装饰器,它们允许在实例化时装饰类成员,因为我希望有一些实例被装饰,而另一些则没有。

在下面的示例中,应用 once 的预期结果SomeClass 实例的装饰器就是当 some_func已调用,调用other_func打印一条消息而不是调用原始函数。

#!/usr/bin/env python

import functools

def some_once(func):
    @functools.wraps(func)
    def wrapped(self, *args, **kwargs):
        if not self._new_attr:
            print("don't have new attr yet")
            func(self, *args, **kwargs)
            self._new_attr = True

    return wrapped

def other_once(func):
    @functools.wraps(func)
    def wrapped(self, *args, **kwargs):
        if self._new_attr:
            print("We have a new attr")
        else:
            func(self, *args, **kwargs)

    return wrapped

def once(cls):
    setattr(cls, "_new_attr", False)
    setattr(cls, "some_func", some_once(cls.some_func))
    setattr(cls, "other_func", other_once(cls.other_func))
    return cls

class SomeClass:

    def some_func(self, parameter):
        return "The parameter is " + str(parameter)

    def other_func(self, parameter):
        return "The other parameter is " + str(parameter)

if __name__ == '__main__':
    a = SomeClass()
    print(dir(a))
    print(a.some_func("p1"))
    print(a.other_func("p2"))

    b = once(SomeClass())
    print(dir(b))
    print(b.some_func("p3"))
    print(b.other_func("p4"))

结果的问题是,而不是看 self._new_attr ,装饰函数改为查看 string._new_attr ,其中字符串是函数的参数。我对我在这里做错了什么感到困惑。

最佳答案

不要装饰实例。创建一个新的、装饰过的类。

更改此行:

b = once(SomeClass())

进入:

b = once(SomeClass)()

应该可以解决问题。 once(SomeClass) 为您提供一个新的、经过修饰的类。在下一步中创建它的一个实例。

关于python - 实例化后装饰类及其成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33432462/

相关文章:

c++ - 装饰者模式在这里是合适的选择吗?

python - 使用属性装饰器的Python类中的属性行为

python - 当我 pip 安装它时,pyproj 无法编译。这不是关于 gcc

python - scipy.fftpack 的内存使用情况

python - seaborn 热图的人工刻度标签

python - 绑定(bind)方法上的装饰器可以访问类及其祖先

python - Python中findall和括号的使用

python - 为什么 Python 没有隐式转换?

python - 解析装饰器中的args和kwargs

python - python 中的互斥装饰器