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

标签 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)

谢谢

最佳答案

继承在这里无济于事。

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

但是,更重要的是,继承的全部意义在于为您提供“is-a”关系。你正在 build 的这个东西不是 deque , 或 heapq -wrapping 对象,它具有您定义的接口(interface)( addget ),恰好使用 dequelistheapq实现。

所以,只要明确地做到这一点。您正在尝试定义一个调用 append 的函数在 deque 上, 或调用 heapq.heappushlist 上.您并不是要编写一个返回执行该操作的函数的柯里化(Currying)函数,而只是一个执行该操作的函数。

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在你的界面中。创建一个返回一个或另一个的工厂函数:

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()

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

关于python - 从python中的 'heapq'和 'deque'继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30156813/

相关文章:

java - 更新元素后重新堆化 java.util.PriorityQueue

python - 需要列列表,其值在pyspark中大于0

python - 隐藏 Python 测验的答案

python - 为什么 user.is_authenticated 在注销后断言为真

c++ - 对可变参数模板多继承函数调用的访问不明确

java - 在 Java 中使用 PriorityQueue 的第 k 个最小数的时间复杂度

python - 在阻塞的 boost c++ 方法中,如何在 Python 中捕获中断信号?

c++ - 构造函数的继承错误调用

c++ - 关于具有虚拟继承的程序输出的混淆

algorithm - 比较二进制堆的插入操作