2016-11-21 2 views
0

Ia имеют следующий контейнер данных, которая постоянно обновляется:UnicodeEncodeError: «ASCII» кодек не может кодировать

data = [] 
     for val, track_id in zip(values,list(track_ids)): 
      #below 
      if val < threshold: 
       #structure data as dictionary 
       pre_data = {"artist": sp.track(track_id)['artists'][0]['name'], "track":sp.track(track_id)['name'], "feature": filter_name, "value": val} 
       data.append(pre_data) 
     #write to file 
     with open('db/json/' + user + '_' + product + '_' + filter_name + '.json', 'w') as f: 
      json.dump(data,f, ensure_ascii=False, indent=4, sort_keys=True) 

, но я получаю много ошибок, как это:

json.dump(data,f, ensure_ascii=False, indent=4, sort_keys=True) File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 190, in dump fp.write(chunk) UnicodeEncodeError: 'ascii' codec can't encode character u'\u2019' in position 6: ordinal not in range(128)

Есть ли способ избавиться от этой проблемы кодирования раз и навсегда?

мне сказали, что это будет сделать это:

import sys 
reload(sys) 
sys.setdefaultencoding('utf-8') 

но многие люди не рекомендуют.

Я использую python 2.7.10

любые улики?

+0

Показать полную ошибку, чтобы мы могли видеть, откуда исходит ошибка. И этот Python 2 или 3? –

+0

'sys.setdefaultencoding', возможно, работал в Python2, но не существует в Python3. И он может работать с 'print()', но не с другим, как запись в файл, поэтому вам нужно показать полное сообщение об ошибке и строку, которая создает проблему. – furas

+0

@MarkRansom обновлен, спасибо –

ответ

0

Когда вы пишете файл, открытый в текстовом режиме, Python кодирует строку для вас. Кодировка по умолчанию - ascii, которая генерирует ошибку, которую вы видите; есть лот символов, которые не могут быть закодированы в ASCII.

Решение состоит в том, чтобы открыть файл в другой кодировке. В Python 2 вы должны использовать модуль codecs, в Python 3 вы можете добавить параметр encoding= непосредственно на open. utf-8 - популярный выбор, поскольку он может обрабатывать все символы Unicode, а для JSON - это стандарт; см. https://en.wikipedia.org/wiki/JSON#Data_portability_issues.

import codecs 
with codecs.open('db/json/' + user + '_' + product + '_' + filter_name + '.json', 'w', encoding='utf-8') as f: 
+0

Ты избил меня! [RFC] (https://tools.ietf.org/html/rfc7159#section-8.1) допускает только кодировки utf-8, utf-16 и utf-32, но накладывает ограничения на два вторых (без спецификации спецификации) и подсказки, что utf-8 - единственный способ взаимодействия. 'mbcs' нарушит rfc. Я думал, что JSON был только utf-8 и был удивлен, что другие кодировки даже разрешены. – tdelaney

+0

@tdelaney Я никогда не имел дело с JSON напрямую, поэтому я не знал о ограничении набора символов, спасибо! Я отредактирую ответ. –

0

Почему бы не кодировать определенную строку вместо этого? попробуйте метод .encode('utf-8') в строке, которая создает исключение.

1

Ваш объект имеет строки unicode и python Поддержка 2.x для unicode может быть немного пятнистой. Во-первых, позволяет сделать небольшой пример, демонстрирующий проблему:

>>> obj = {"artist":u"Björk"} 
>>> import json 
>>> with open('deleteme', 'w') as f: 
...  json.dump(obj, f, ensure_ascii=False) 
... 
Traceback (most recent call last): 
    File "<stdin>", line 2, in <module> 
    File "/usr/lib/python2.7/json/__init__.py", line 190, in dump 
    fp.write(chunk) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 3: ordinal not in range(128) 

С текстом json.dump справки:

Ах! Это решение. Либо используйте значение по умолчанию ensure_ascii=True и получите ascii экранированные символы Unicode, либо используйте модуль codecs, чтобы открыть файл с нужной кодировкой. Это работает:

>>> import codecs 
>>> with codecs.open('deleteme', 'w', encoding='utf-8') as f: 
...  json.dump(obj, f, ensure_ascii=False) 
... 
>>> 
Смежные вопросы