Pickle functools包装器错误:无法pickle functools.KeyWrapper对象

问题描述 投票:1回答:1

我试图挑选一个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()函数的情况下,酸洗工作正常,但我需要它,因为我的函数不是关键函数。

python python-3.x pickle sortedlist functools
1个回答
2
投票

问题似乎是cmp_tp_keynow 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'>)
© www.soinside.com 2019 - 2024. All rights reserved.