[本周早些时候,我向相关的SO社区询问了有关使用OOP构造数学树的通用question。主要的收获是,复合模式和解释器模式是这种应用程序的首选模式。
然后,我花了几天时间在网上四处寻找有关如何构造这些资源的资源。我仍然坚信,我不需要构造一个完整的解释器,并且复合结构可能足以满足我的目的。
从另一个问题开始,我试图构造这棵树:
如果不使用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()
但是,我陷入了最后一行。似乎如果我在复合类实例component_method
的级别上调用e
,它将无法正常工作,因为该体系结构并未构建为可处理添加两个Child或Composite对象的情况。
我该如何使用它?我的component_method
类的CompositeElement
应该包含什么?
谢谢
def component_method(self):
values = [child.component_method() for child in self.children]
return self.func(*values)
这将评估子节点,并将值传递给节点本身的函数,并返回值。