我必须遵循以下类,该类将使对象具有可从类变量派生的可链接方法。由于此代码是非常重复的代码,因此我面临的挑战是制作一个可以应用于方法a
,b
和c
的装饰器。我面临的问题是,我似乎找不到找到构造返回该实例(self
)的包装器的方法。有没有更好的方法来构造它?
class Test:
def __init__(self, a, b, c):
self._a = a
self._b = b
self._c = c
self.call_chain = []
def a(self, truth):
def func():
return self._a == truth
self.call_chain.append(func)
return self
def b(self, truth):
def func():
return self._b == truth
self.call_chain.append(func)
return self
def c(self, val):
def func():
return self._c == val
self.call_chain.append(func)
return self
def evaluate(self):
try:
for f in self.call_chain:
if f() == False:
raise ValueError('False encountered')
except ValueError:
self.call_chain.clear()
return False
self.call_chain.clear()
return True
它的工作方式如下:
c = Test(True, False, 13)
c.a(True).b(False).c(13).evaluate()
答案 0 :(得分:1)
技巧是将参数存储到函数中,作为调用链的一部分。最简单的方法是使用functools.partial
个对象。
from functools import wraps, partial
def chain(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
suspended = partial(func, self, *args, **kwargs)
self.call_chain.append(suspended)
return self
return wrapper
class Test:
def __init__(self, a, b, c):
self.call_chain = []
self._a = a
self._b = b
self._c = c
@chain
def a(self, val):
return self._a == val
@chain
def b(self, val):
return self._b == val
@chain
def c(self, val):
return self._c == val
def evaluate(self):
try:
for f in self.call_chain:
if f() == False:
raise ValueError('False encountered')
except ValueError:
self.call_chain.clear()
return False
self.call_chain.clear()
return True
c = Test(True, False, 13)
c.a(True).b(False).c(13).evaluate() # True
c.a(True).b(False).c(11).evaluate() # False