我试图动态地实现'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
问题是使用
调用heapqheappush(Q, elem)
并使用
排队Q.append(elem)
我希望这一点很明确。我认为应该有办法解决这个问题(也许使用lambda)
由于
答案 0 :(得分:4)
继承在这里没有帮助。
首先,heapq
甚至不是一个类,所以你不能继承它。您可以编写一个包含其功能的类(或者在ActiveState配方或PyPI包中找到一个),但是您必须要继承一个类。
但是,更重要的是,整个继承点就是给你一个" is-a"关系。你正在构建的这个东西不是deque
,或是heapq
- 包装对象,它是一个你已经定义的界面({{1和} add
)恰好使用get
或deque
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
现在你得到了相同的结果,但是代码更容易理解(如果你关心的话,效率稍高一些......)。