【问题标题】:Pickle functools wrapper error: can't pickle functools.KeyWrapper objectsPickle functools wrapper 错误:不能pickle functools.KeyWrapper 对象
【发布时间】:2018-06-07 16:16:44
【问题描述】:

我正在尝试腌制一个 SortedListWithKey,我正在使用 functools 中的 cmp_to_key() 将比较函数转换为键函数。 但是, cmp_to_key() 似乎使我的对象不可拾取,并且出现以下错误: TypeError: can't pickle functools.KeyWrapper objects

我该如何解决?这是重现错误的代码示例:

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

【问题讨论】:

  • 发电机可以腌制吗?也许试试:list(SortedListWithKey(...))?请参阅:stackoverflow.com/questions/7180212/… 使用 key kwarg 我认为它会将其变成发电机?
  • 一个很老的问题,不是每个对象都可以腌制。尝试转换为一些基本对象。
  • 你不能腌制一个函数(任何类型的)。不过,有一个名为 dill 的模块应该能够做到这一点。

标签: python python-3.x pickle sortedlist functools


【解决方案1】:

问题似乎是cmp_tp_keynow written in C,并且它返回的类既不是pickleable 也不是subclassable。不过,原来的纯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'>)

【讨论】:

    猜你喜欢
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-22
    相关资源
    最近更新 更多