AttributeError: Can't pickle local object '<locals>.<lambda>' [重复]

问题描述 投票:0回答:2

我正在尝试腌制使用以下方法创建的嵌套字典:

collections.defaultdict(lambda: collections.defaultdict(int))

我的简化代码是这样的:

class A:
  def funA(self):
    #create a dictionary and fill with values
    dictionary = collections.defaultdict(lambda: collections.defaultdict(int))
    ...
    #then pickle to save it
    pickle.dump(dictionary, f)

但是它给出了错误:

AttributeError: Can't pickle local object 'A.funA.<locals>.<lambda>'

打印字典后显示:

defaultdict(<function A.funA.<locals>.<lambda> at 0x7fd569dd07b8> {...}

我尝试在该函数中使字典成为全局但错误是相同的。 我感谢对此问题的任何解决方案或见解。谢谢!

python python-3.6 pickle python-3.7 jsonpickle
2个回答
7
投票

pickle
记录对函数的引用(模块和函数名称),而不是函数本身。 unpickling 时,它将加载模块并按名称获取函数。
lambda
创建匿名函数对象,这些对象没有名称并且加载程序无法找到。解决方案是切换到命名函数。

def create_int_defaultdict():
    return collections.defaultdict(int)

class A:
  def funA(self):
    #create a dictionary and fill with values
    dictionary = collections.defaultdict(create_int_defaultdict)
    ...
    #then pickle to save it
    pickle.dump(dictionary, f)

0
投票

正如@tdlaney 所解释的,

lambda
创建了一个不能被腌制的匿名函数。最简洁的解决方案是将
lambda
替换为
partial
(不需要新功能):

from functools import partial

class A:
  def funA(self):
    #create a dictionary and fill with values
    dictionary = collections.defaultdict(partial(collections.defaultdict, int))
    ...
    #then pickle to save it
    pickle.dump(dictionary, f)
© www.soinside.com 2019 - 2024. All rights reserved.