我正在尝试创建一些装饰器,它们允许在实例化时装饰类成员,因为我希望有一些实例被装饰,而另一些则没有。
在下面的示例中,应用 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/