在python中继承'heapq'和'deque'?

时间:2015-05-10 21:22:38

标签: python multiple-inheritance priority-queue deque

我试图动态地实现'heapq'或'deque'(根据用户的输入)

class MyClass():

    def __init__(self,  choose = True ):
    self.Q = []
    self.add = self.genAdd(choose)
    self.get = self.genGet(choose)

    def genAdd(self, ch):
        if(ch == True):
            def f(Q, elem):
                return Q.append
        else:
            def f(Q):
                return heappush
        return f

和'genGet'相同

执行在一侧(x)或另一侧(但不是两者同时)是正确的。我得到像

这样的东西
TypeError: f() takes exactly 1 argument (2 given)

尝试了多次入侵,但得到了

TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

问题是使用

调用heapq
heappush(Q, elem)

并使用

排队
Q.append(elem)

我希望这一点很明确。我认为应该有办法解决这个问题(也许使用lambda)

由于

1 个答案:

答案 0 :(得分:4)

继承在这里没有帮助。

首先,heapq甚至不是一个类,所以你不能继承它。您可以编写一个包含其功能的类(或者在ActiveState配方或PyPI包中找到一个),但是您必须要继承一个类。

但是,更重要的是,整个继承点就是给你一个" is-a"关系。你正在构建的这个东西不是deque,或是heapq - 包装对象,它是一个你已经定义的界面({{1和} add)恰好使用getdeque list来实现。

所以,明确地这样做。您正在尝试定义一个功能,该功能可以在heapq上调用append,或在deque上调用heapq.heappush。你并没有试图写一个curried函数来返回一个执行该事情的函数,只是一个执行该事情的函数。

list

这里还有一些其他问题。首先,如果你想要一个双端队列,你肯定需要设置def genAdd(self, ch): # As a side note, you don't need to compare == True, nor # do you need to wrap if conditions in parens. if ch: def f(elem): self.Q.append(elem) else: def f(elem): heappush(self.Q, elem) return f 而不是self.Q = deque()。并且您可能希望将这些函数包装为self.Q = []而不是使用types.MethodType作为闭包变量(这将起作用,它的可读性较差,因为许多人可能不太清楚人为什么它有效)。等等。但这是根本问题。

例如:

self

这将打印:

from collections import deque
from heapq import heappush

class MyClass(object):
    def __init__(self, choose=True):
        self.Q = deque() if choose else []
        self.add = self.genAdd(choose)

    def genAdd(self, ch):
        if ch:
            def f(elem):
                self.Q.append(elem)
        else:
            def f(elem):
                heappush(self.Q, elem)
        return f

d = MyClass(True)
d.add(3)
d.add(2)
print(d.Q)

h = MyClass(False)
h.add(3)
h.add(2)
print(h.Q)

话虽如此,可能还有更好的设计:创建一个在您的界面中包裹deque([3, 2]) [2, 3] 的类。在您的界面中创建另一个包含deque list的类。创建一个返回一个或另一个的工厂函数:

heapq

现在你得到了相同的结果,但是代码更容易理解(如果你关心的话,效率稍高一些......)。