我想在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
我会避免通过构造一个要返回的新对象来改变Test
的状态。这是一个简洁的版本,但它不一定能很好地扩展:
@classmethod
def is_not(cls, truth):
test = cls(not self.a, not self.b)
test._validity = not(truth)
return test
这也会产生双重负面影响,这可能不是你想要的。
这让人想起Monad模式。实现这一目标的一种可能方法是使用来自State
的oslash
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()
部分做的。