【问题标题】:Decorating class and its members after instantiation实例化后装饰类及其成员
【发布时间】:2015-10-30 09:19:07
【问题描述】:

我正在尝试创建一些允许在实例化时对类成员进行装饰的装饰器,因为我希望有一些经过装饰的实例,而另一些则没有。

在下面的示例中,将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,其中字符串是函数的参数。我对我在这里做错了什么感到困惑。

【问题讨论】:

    标签: python decorator


    【解决方案1】:

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

    改变这一行:

    b = once(SomeClass())
    

    进入:

    b = once(SomeClass)()
    

    应该做的伎俩。 once(SomeClass) 为您提供了一个新的装饰类。在下一步中创建它的一个实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-28
      • 1970-01-01
      • 2014-05-18
      • 2014-02-02
      • 1970-01-01
      • 2019-02-03
      相关资源
      最近更新 更多