如何使用cPickle将包含utf-8字符键的字典保存到文件?

2 投票
2 回答
1495 浏览
提问于 2025-04-16 13:15

我想知道如何在Python中使用cPickle把一个包含utf-8字符作为键的字典保存到文件里?这个字典非常大,我听说cPicklepickle快得多。而且我觉得使用utf-8编码的键可能也会有问题。其他快速的解决方案也欢迎分享。

这是我现在的做法,下面是错误信息:

unique_ngrams_dict = defaultdict(lambda: 0)# just to show how I defined my dict


dict_file = codecs.open('ngram_dict', 'w', 'utf-8')
cPickle.dump(unique_ngrams_dict,dict_file)
dict_file.close()

错误信息:

Traceback (most recent call last):
  File "Generate_NGram.py", line 81, in <module>
    save_ngram_dict(unique_ngrams_dict)
  File "Generate_NGram.py", line 70, in save_ngram_dict
    cPickle.dump(unique_ngrams_dict,dict_file)
  File "/usr/lib/python2.6/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle function objects

谢谢

2 个回答

0

你只需要去做,相信pickle模块会处理好一切。对待pickle最好的方式就是把它当成一个神秘的东西,当你把它解开时,它会神奇地恢复成你最开始的数据结构。

不要试图对pickle的输出进行任何编码,它应该被当作一个二进制的块来处理。如果你在使用pickle时有unicode元素,解开后它们仍然会是unicode。

2
  1. Pickle是一种二进制格式,所以你不应该用任何编码方式打开这个文件,只需:

    file('ngram_dict', 'w')
    

    这并不是导致失败的原因,只是效率不高。

  2. 真正的问题是你想保存的对象里面包含了一个函数的引用(默认值是lambda: 0),而pickle格式不支持序列化函数。

    你有三个选择:

    1. 使用一个普通的dict,然后用它的.get方法和默认参数。
    2. 在进行pickle操作之前设置

      unique_ngrams_dict.default_factory = None
      

      然后在反序列化后再设置回

      unique_ngrams_dict.default_factory = lambda: 0
      

    3. 定义一个像这样的类:

      class NgramDefault:
          def __call__():
              return 0
      

      并用NgramDefault()作为默认工厂,而不是lambda: 0

撰写回答