无需构建解释器即可评估树 (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)
这将评估子节点并将值传递给节点本身的函数,返回值。
本周早些时候,我在相关的 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)
这将评估子节点并将值传递给节点本身的函数,返回值。