从 python 中的 'heapq' 和 'deque' 继承?

Inherit from both 'heapq' and 'deque' in python?

我正在尝试动态实施 '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)

谢谢

继承在这里无济于事。

首先,heapq 甚至不是 class,因此您不能继承它。你可以写一个 class 来包装它的功能(或者在 ActiveState 食谱或 PyPI 包中找到一个),但是你必须有一个 class 才能继承。

但是,更重要的是,继承的全部意义在于为您提供 "is-a" 关系。您正在构建的这个东西不是 dequeheapq 包装对象,它是具有您定义的接口的东西(addget) 恰好使用 dequelistheapq 来实现。

所以,明确地做到这一点。您正在尝试定义一个函数,该函数要么在 deque 上调用 append,要么在 list 上调用 heapq.heappush。您不是在尝试编写一个 returns 函数来做这件事的柯里化函数,只是一个函数来做这件事。

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]

也就是说,可能有更好的设计:创建一个 class 在您的界面中包装 deque。创建另一个 class,在您的界面中用 heapq 包装 list。创建一个 returns 一个或另一个的工厂函数:

class _MyClassDeque(object):
    def __init__(self):
        self.Q = deque()
    def add(self, elem):
        self.Q.append(elem)

class _MyClassHeap(object):
    def __init__(self):
        self.Q = []
    def add(self, elem):
        heappush(self.Q, elem)

def MyClass(choose=True):
    return _MyClassDeque() if choose else _MyClassHeap()

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