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

时间:2011-03-08 13:20:21

标签: python dictionary pickle

我想知道如何使用cPickle将包含utf-8字符的字典保存为Python中文件的键?这本字典非常大,我听说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 :(得分:2)

  1. Pickle是一种二进制格式,因此您不应该使用任何编解码器打开该文件,只需:

    file('ngram_dict', 'w')
    

    这不是它失败的原因,只是非常低效。

  2. 实际问题是您尝试保存的对象包含函数引用 (默认值lambda: 0)和pickle格式不支持序列化函数。

    您将有三种选择:

    1. 使用常规dict并使用默认参数的.get方法。
    2. unique_ngrams_dict.default_factory = None
      
      在酸洗之前

      并将其重新设置为

      unique_ngrams_dict.default_factory = lambda: 0
      

    3. 定义一个类:

      class NgramDefault:
          def __call__():
              return 0
      

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

答案 1 :(得分:0)

你应该这样做,并相信pickle模块做正确的事情。处理泡菜的最好方法是作为一个不透明的东西,它会神奇地重新创建你在解开它时开始的确切数据结构。

不要尝试对pickle的输出应用任何类型的编码,它应该被视为二进制blob。如果你在pickle时有unicode元素,一旦你unpickle它们将是unicode。