继承方法的正确方法有1个更正

2024-09-30 14:17:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我在做数据结构的家庭作业时用python做了一点面向对象的实验,我在理解如何用修正继承一些方法时遇到了一些困难

所以,我有:

class BinarySearchTree(object):
    # snipped
    def _insert(self, key, val):
        prevNode = None
        currentNode = self.root
        while currentNode:
            prevNode = currentNode
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped                

以及:

class RBTree(BinarySearchTree): 
    # snipped
    def _insert(self, key, val):
        prevNode = None
        currentNode = self.root
        while currentNode:
            prevNode = currentNode  
            prevNode.size += 1 # The only difference is in this line
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped

我的问题是:有没有一种聪明的方法来继承这个方法并实现这个差异(prevNode.size += 1),而不复制整个继承的函数代码

p.S.:对不起,我的英语不好

UPD:现在我无法在斯科特和卡布的解决方案之间做出选择


Tags: 方法keyselfnodeifvalelseclass
3条回答

假设prevNode也是BTreeRBTree,您可以添加另一个方法,比如'updateSize',并包含行

prevNode.updateSize()

BTree中,这不会起任何作用。但是如果将RBTree设为BTRee的子类,则可以重写此方法以将1添加到节点的大小

它不太优雅,但你可以这样做:

class BinarySearchTree(object):
    def _insert(self, key, val, update=False):
       prevNode = None
       currentNode = self.root
        while currentNode:
            prevNode = currentNode
            if update:
                prevNode.size += 1
            if key < currentNode.key:
                currentNode = currentNode.leftChild
            else:
                currentNode = currentNode.rightChild

        if key < prevNode.key:                      
            prevNode.leftChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.leftChild)            
        else:                                       
            prevNode.rightChild = self.Node(key, val, parent=prevNode)
            self.updateNodeProperties(prevNode.rightChild)
    # snipped  

class RBTree(BinarySearchTree): 
    # snipped

    def _insert(self, key, val):
        super(RBTree, self)._insert(self, key, val, update=True)

我真的不喜欢这样,因为它在你的BinarySearchTree类中有代码来更新一个实例变量,这个实例变量除了在派生的RBTree类中之外是不存在的,但是由于这部分代码不应该为BinarySearchTree实例执行,所以你不应该遇到NameError

这里有一个使用访问者设计模式的建议

在这种模式中,您正在编写一个visitor方法,而不知道访问的每个节点需要做什么

我们将更改基类以添加访问者功能

class BinarySearchTree(object):
# snipped
def _insert(self, key, val, visitor=None):   # Change here
    prevNode = None
    currentNode = self.root
    while currentNode:
        prevNode = currentNode
        if visitor: visitor(prevNode)       # Change here
        if key < currentNode.key:
            currentNode = currentNode.leftChild
        else:
            currentNode = currentNode.rightChild

    if key < prevNode.key:                      
        prevNode.leftChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.leftChild)            
    else:                                       
        prevNode.rightChild = self.Node(key, val, parent=prevNode)
        self.updateNodeProperties(prevNode.rightChild)
# snipped   

现在是你的第二节课

class RBTree(BinarySearchTree): 
# snipped
def _insert(self, key, val):
    visitor = lambda node: node.size += 1
    super(RBTree, self)._insert(self, key, val, visitor)
# snipped 

相关问题 更多 >