通过1次校正继承方法的正确方法

时间:2016-09-16 19:13:35

标签: python python-2.7 inheritance

我在python中尝试了一点OOP,同时在数据结构上做了功课,我在理解如何纠正继承一些带有更正的方法时遇到了一些麻烦。

所以,我有:

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

我的问题是:有没有聪明的方法来继承这个方法并实现这个差异(attrs="{'invisible': [('condition','=', True)]}")而不复制整个继承的函数代码?

P.S。:抱歉我的英语不好。

UPD:现在我无法在Scott和CAB的解决方案中做出选择......

3 个答案:

答案 0 :(得分:2)

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

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 ...

答案 1 :(得分:1)

假设prevNode也是BTreeRBTree,您可以添加其他方法,例如'updateSize`,并包含该行

prevNode.updateSize()

BTree中,这不会做任何事情。但是,如果您将RBTree设为BTRee的子类,则可以覆盖此方法以将1添加到节点的大小。

答案 2 :(得分:1)

以下是使用访客设计模式的建议。

在这种模式中,您正在编写一个访问者方法,而不是具体了解每个访问过的节点需要做什么。

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

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