我试图挑选一个SortedListWithKey,我从functools使用cmp_to_key()将比较函数转换为关键函数。但是,cmp_to_key()似乎使我的对象不可用,我得到以下错误:TypeError:无法pickle functools.KeyWrapper对象
我该如何解决?这是重现错误的代码示例:
import pickle
from functools import cmp_to_key
from sortedcontainers import SortedListWithKey
def order_fun(a, b):
if abs(a[0]-b[0]) < 1e-8:
return 0
elif a[0]-b[0] > 0:
return 1
else:
return -1
pickle.loads(pickle.dumps(SortedListWithKey([[1,2], [3,4]], key=cmp_to_key(order_fun))))
谢谢!
注意:在不使用cmp_to_key()函数的情况下,酸洗工作正常,但我需要它,因为我的函数不是关键函数。
问题似乎是cmp_tp_key是now written in C,它返回的类既不是pickleable也不是子类。但是,原始的纯python版本是still maintained in the source,而且非常简单。当这与您的示例一起使用时,它可以正常工作。当然,明显的缺点是纯python版本较慢 - 但the difference is not huge。
这是您的示例的工作版本:
import pickle
from sortedcontainers import SortedListWithKey
def order_fun(a, b):
if abs(a[0]-b[0]) < 1e-8:
return 0
elif a[0]-b[0] > 0:
return 1
else:
return -1
class KeyFunc(object):
__slots__ = ['obj']
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return order_fun(self.obj, other.obj) < 0
def __gt__(self, other):
return order_fun(self.obj, other.obj) > 0
def __eq__(self, other):
return order_fun(self.obj, other.obj) == 0
def __le__(self, other):
return order_fun(self.obj, other.obj) <= 0
def __ge__(self, other):
return order_fun(self.obj, other.obj) >= 0
__hash__ = None
sl = SortedListWithKey([[1,2], [3,4]], key=KeyFunc)
print(sl)
print(pickle.loads(pickle.dumps(sl)))
输出:
SortedListWithKey([[1, 2], [3, 4]], key=<class '__main__.KeyFunc'>)
SortedListWithKey([[1, 2], [3, 4]], key=<class '__main__.KeyFunc'>)