dev*_*v93 3 python priority-queue multiple-inheritance 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
Run Code Online (Sandbox Code Playgroud)
'genGet' 也一样
执行在一侧 (x) 或另一侧(但不能同时进行)是正确的。我得到类似的东西
TypeError: f() takes exactly 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)
尝试了多次继承,但得到了
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
Run Code Online (Sandbox Code Playgroud)
问题是 heapq 被调用
heappush(Q, elem)
Run Code Online (Sandbox Code Playgroud)
并排队
Q.append(elem)
Run Code Online (Sandbox Code Playgroud)
我希望重点是明确的。我认为应该有办法解决这个问题(也许使用 lambda)
谢谢
继承在这里没有帮助。
首先,heapq它甚至不是一个类,所以你不能继承它。您可以编写一个包含其功能的类(或在 ActiveState 配方或 PyPI 包中找到一个),但您必须有一个类来继承。
但是,更重要的是,继承的全部意义在于给你一个“is-a”关系。您正在构建的这个东西不是 -adeque或heapq-wrapping 对象,它是一个带有您定义的接口(add和get)的东西,碰巧使用 adeque或 a listwithheapq来实现。
所以,只要明确地做到这一点。你试图定义一个函数,要么调用append上deque,或电话heapq.heappush上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
Run Code Online (Sandbox Code Playgroud)
这里还有一些其他问题。首先,你肯定需要设置self.Q = deque()而不是self.Q = []如果你想要一个双端队列。并且您可能希望将这些函数包装为 atypes.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)
Run Code Online (Sandbox Code Playgroud)
这将打印:
deque([3, 2])
[2, 3]
Run Code Online (Sandbox Code Playgroud)
话虽如此,可能有更好的设计:创建一个将 a 包装deque在您的界面中的类。创建另一个在您的界面中包装listwith 的类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()
Run Code Online (Sandbox Code Playgroud)
现在你得到了相同的结果,但代码更容易理解(并且稍微更高效,如果你关心......)。