Как сохранить словарь, содержащий символы utf-8 в качестве ключей, в файл с cPickle Python? - PullRequest
2 голосов
/ 08 марта 2011

Я хочу знать, как сохранить словарь, содержащий символы utf-8 в качестве ключей для файла в Python с cPickle?этот словарь очень большой, и я слышал, что cPickle намного быстрее, чем pickle.Кроме того, я полагаю, что наличие ключей в кодировке 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 ]

2 голосов
/ 08 марта 2011
  1. Pickle - это двоичный формат , поэтому вы не должны открывать файл с какими-либо кодеками, просто:

    file('ngram_dict', 'w')
    

    Это не причина, по которой он не работает, просто совершенно неэффективно.

  2. Фактическая проблема - объект, который вы пытаетесь сохранить, содержит ссылку на функцию (значение по умолчанию lambda: 0), а формат pickle не поддерживает функции сериализации.

    У вас будет три варианта:

    1. Используйте обычный dict и используйте его .get метод с аргументом по умолчанию.
    2. Set

      unique_ngrams_dict.default_factory = None
      

      до травления и установите его на

      unique_ngrams_dict.default_factory = lambda: 0
      

      после травления.

    3. Определите класс как:

      class NgramDefault:
          def __call__():
              return 0
      

      и использовать NgramDefault() в качестве фабрики по умолчанию вместо lambda: 0.

0 голосов
/ 08 марта 2011

Вы должны просто сделать это и доверять модулю рассола, чтобы делать правильные вещи.Лучший способ обработать засолку - это непрозрачный объект, который волшебным образом воссоздает структуру данных, с которой вы начали, когда вы ее извлекаете.

Не пытайтесь применить какую-либо кодировку к выводумаринованные, это следует рассматривать как двоичный блоб.Если у вас есть элементы Unicode при мариновании, они будут Unicode после того, как вы откинули.

...