我想在python中实现类似对象的查询,该查询在后台使用方法链设计来评估有效性:
c = Test(a=True, b=False)
c.a.is_not(b).validity()
或者我可以做到
c.is_not(a).b.validity()
或这个
c.is_not(a).is_not(b).validity()
或类似的
c.is_not(a).is_not(b).validity()
我面临的挑战是添加一个逆向查询,例如可以接受属性方法并返回逆向真相的方法。
这是我的尝试。但是我意识到这不是一个好方法,因为在调用is_not()
的情况下,有效性将被更改两次:
class Test:
def __init__(self, a, b):
self._a = a
self._b = b
self._validity = True
@property
def a(self):
self._validity = self._validity == self._a
return self
@property
def b(self):
self._validity = self._validity == self._b
return self
def is_not(self, truth):
truth = not(truth)
self._validity = self._validity == truth
return self
def validity(self):
return self._validity
答案 0 :(得分:1)
我将避免通过构造要返回的新对象来更改Test
的状态。这是一个简洁的版本,但不一定能很好地扩展:
@classmethod
def is_not(cls, truth):
test = cls(not self.a, not self.b)
test._validity = not(truth)
return test
这还具有双重负数将变为正数的效果,这可能不是您想要的。
这让人联想到Monad模式。一种实现此目的的可能方法是使用oslash
中的State
monad:
import oslash
class TestMonadic:
def __init__(self, a, b):
self.a = a
self.b = b
def is_not(self, truth: bool) -> oslash.State:
return lambda validity: oslash.State(lambda _: (truth != validity, self))
def validity(self, state: oslash.State):
return state.run(self)[0]
该语法在python中变得有点麻烦,因为它不是为此设计的。将is_not
和validity
放在类之外可能更有意义,但是由于它们的名称比较笼统,将它们绑定到类上很有帮助。 (在Haskell中,函数名称不是那么重要,因为函数类型签名会触发调度。)
在此框架中,计算结果如下:
>>> t = TestMonadic(a=True, b=False)
>>> t.validity(State.get() | t.is_not(t.b))
True
>>> t.validity(State.get() | t.is_not(t.a) | t.is_not(t.b))
True
>>> t.validity(State.get() | t.is_not(t.b))
False
oslash
缺少evalState
,这是validity()
的部分工作。