真值评估链法与逆转法

时间:2019-02-14 10:23:41

标签: python python-3.x method-chaining

我想在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

1 个答案:

答案 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_notvalidity放在类之外可能更有意义,但是由于它们的名称比较笼统,将它们绑定到类上很有帮助。 (在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()的部分工作。