从python中的“heapq”和“deque”继承?

2024-10-06 11:25:08 发布

您现在位置: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)或另一边(但不能同时执行)执行正确。我得到的东西像

^{pr2}$

尝试过多次重复

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)

谢谢


Tags: oftheselftruereturndefchclass
1条回答
网友
1楼 · 发布于 2024-10-06 11:25:08

继承在这里没用。在

首先,heapq甚至不是一个类,所以不能从它继承。您可以编写一个类来包装它的功能(或者在ActiveState recipes或PyPI包中找到一个),但是必须要有一个类才能继承。在

但是,更重要的是,继承的全部意义在于给你一种“是-一种”的关系。您正在构建的这个东西不是一个deque,或者heapq-包装对象,它是一个你定义的接口(add和{})的东西,它碰巧使用deque或带有{}的list。在

所以,明确地说。您试图定义一个函数,该函数要么在deque上调用append,要么在list上调用heapq.heappush。你并不是要写一个curried函数,它返回一个执行该操作的函数,而只是一个执行该操作的函数。在

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

这里还有一些其他问题。首先,如果您想要一个deque,您肯定需要设置self.Q = deque(),而不是{}。您可能希望将这些函数包装为types.MethodType,而不是使用self作为闭包变量(这会起作用,只是可读性较差,因为许多人可能不清楚为什么它会起作用)。等等。但这是根本问题。在


例如:

^{pr2}$

这将打印:

deque([3, 2])
[2, 3]

也就是说,可能还有更好的设计:创建一个类,在接口中包装deque。创建另一个类,在接口中用heapq包装list。创建返回一个或另一个的工厂函数:

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

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

相关问题 更多 >