无需构建解释器即可评估树 (Python)

Evaluating tree without having to build an interpreter (Python)

本周早些时候,我在相关的 SO 社区中询问了 generic question 关于使用 OOP 构建数学树的问题。主要收获是 Composite 和 Interpreter 模式是此类应用程序的首选模式。

然后我花了几天时间在网上四处寻找有关如何构建它们的资源。我仍然相信我不需要构造一个完整的解释器,一个复合解释器可能就足以满足我的目的。

从另一个问题我试图构建这棵树:

如果不使用 OOP,我可能会这样做:

import numpy as np

def root(B, A):
    return B+A

def A(x,y,z):
    return x*np.log(y)+y**z

def B(alpha, y):
    return alpha*y

def alpha(x,y,w):
    return x*y+w

if __name__=='__main__':

    x,y,z,w = 1,2,3,4
    result = root(B(alpha(x,y,w),y), A(x,y,z))

这将给出 20.693147180559947 的正确结果。我尝试使用复合模式来做类似的事情:

class ChildElement:
    '''Class representing objects at the bottom of the hierarchy tree.'''
    def __init__(self, value):
        self.value = value
    def __repr__(self):
        return "class ChildElement with value"+str(self.value)
    def component_method(self):
        return self.value
        

class CompositeElement:
    '''Class representing objects at any level of the hierarchy tree except for the bottom level.
      Maintains the child objects by adding and removing them from the tree structure.'''
    def __init__(self, func):
        self.func = func
        self.children = []
    def __repr__(self):
        return "class Composite element"
    def append_child(self, child):
        '''Adds the supplied child element to the list of children elements "children".'''
        self.children.append(child)
    def remove_child(self, child):
        '''Removes the supplied child element from the list of children elements "children".'''
        self.children.remove(child)
    def component_method(self):
        '''WHAT TO INCLUDE HERE?'''


if __name__=='__main__':

    import numpy as np
    
    def e_func(A, B):
        return A+B
        
    def A_func(x,y,z):
        return x*np.log(y)+y**z
        
    def B_func(alpha,y):
        return alpha*y
        
    def alpha_func(x,y,w):
        return x*y+w

    x = ChildElement(1)
    y = ChildElement(2)
    z = ChildElement(3)
    w = ChildElement(4)
    
    e = CompositeElement(e_func)
    A = CompositeElement(A_func)
    B = CompositeElement(B_func)
    alpha = CompositeElement(alpha_func)
    
    e.children = [A, B]
    A.children = [x, y, z]
    B.children = [alpha, y]
    alpha.children = [x, y, w]
    e.component_method()

然而,我卡在了最后一行。似乎如果我在复合 class 实例 e 级别调用 component_method,它将不起作用,因为该体系结构不是为处理添加两个子对象或复合对象而构建的。

我怎样才能让它工作?我的 CompositeElement class 的 component_method 应该包含什么?

def component_method(self):
    values = [child.component_method() for child in self.children]
    return self.func(*values)

这将评估子节点并将值传递给节点本身的函数,返回值。