У меня есть следующий сценарий, чтобы прочитать UTF-8 CSV:CSV dictReader кодирование не исправить
def readCSV(f, bdgs):
with open(f) as csvfile:
reader = csv.DictReader(csvfile, delimiter=';')
for row in reader:
for key, val in row.iteritems():
print type(key), key,':',type(val),val
print type(row), row
if row['OBJECTID'] is not '':
# do some magic
, которые дают это:
processing the following files: ['Fenetre.csv']
<type 'str'> Type de fenêtre_uniqueid : <type 'str'> uid-100
<type 'str'> Type de fenêtre_CheckDelete : <type 'str'>
<type 'str'> Type de fenêtre_Nom : <type 'str'> Fenetre 2006-2010
<type 'str'> Type de fenêtre_Intercalaire : <type 'str'> 1
<type 'str'> Liste des fenêtres_Hauteur : <type 'str'> 3.29
<type 'str'> OBJECTID : <type 'str'> 3760
<type 'str'> Liste des fenêtres_Nb vantaux : <type 'str'> 2
<type 'str'> Liste des fenêtres_Façade : <type 'str'> uid-001-AW1
<type 'str'> Type de fenêtre_Cadre : <type 'str'> 7
<type 'str'> Type de fenêtre_vitrage : <type 'str'> 4
<type 'str'> Liste des fenêtres_Part cadre : <type 'str'> 20
<type 'str'> Liste des fenêtres_Nom : <type 'str'> f1
<type 'str'> Liste des fenêtres_Nombre : <type 'str'> 1
<type 'str'> Liste des fenêtres_Ombrage1 : <type 'str'> uid-201
<type 'str'> Liste des fenêtres_Largeur : <type 'str'> 1.55
<type 'str'> Liste des fenêtres_Ombrage2 : <type 'str'>
<type 'str'> Liste des fenêtres_CheckDelete : <type 'str'>
<type 'str'> Liste des fenêtres_Type de fenêtre : <type 'str'> uid-100
<type 'dict'> {'Type de fen\xc3\xaatre_uniqueid': 'uid-100', 'Type de fen\xc3\xaatre_CheckDelete': '', 'Type de fen\xc3\xaatre_Nom': 'Fenetre 2006-2010', 'Type de fen\xc3\xaatre_Intercalaire': '1', 'Liste des fen\xc3\xaatres_Hauteur': '3.29', '\xef\xbb\xbfOBJECTID': '3760', 'Liste des fen\xc3\xaatres_Nb vantaux': '2', 'Liste des fen\xc3\xaatres_Fa\xc3\xa7ade': 'uid-001-AW1', 'Type de fen\xc3\xaatre_Cadre': '7', 'Type de fen\xc3\xaatre_vitrage': '4', 'Liste des fen\xc3\xaatres_Part cadre': '20', 'Liste des fen\xc3\xaatres_Nom': 'f1', 'Liste des fen\xc3\xaatres_Nombre': '1', 'Liste des fen\xc3\xaatres_Ombrage1': 'uid-201', 'Liste des fen\xc3\xaatres_Largeur': '1.55', 'Liste des fen\xc3\xaatres_Ombrage2': '', 'Liste des fen\xc3\xaatres_CheckDelete': '', 'Liste des fen\xc3\xaatres_Type de fen\xc3\xaatre': 'uid-100'}
Traceback (most recent call last):
File "./oba.py", line 120, in <module>
sys.exit(main())
File "./oba.py", line 115, in main
readCSV(f,out)
File "./oba.py", line 37, in readCSV
if row['OBJECTID'] is not '':
KeyError: 'OBJECTID'
, если вы посмотрите на последнюю строку до трассировки стека , вы видите, что хотя кодировка для ключей и строк значений в первой строке все правильно. dict не сохраняет ключ/значения с надлежащим кодированием. Отсюда и ошибка.
Для того, чтобы исправить эту проблему, я попытался это:
def unicodeDictReader(utf8_data, **kwargs):
csv_reader = csv.DictReader(utf8_data, **kwargs)
for row in csv_reader:
yield {unicode(key, 'utf-8') : unicode(value, 'utf-8') for key, value in row.iteritems()}
def readCSV(f, bdgs):
js=getJSONmap()
with open(f) as csvfile:
reader = unicodeDictReader(csvfile, delimiter=';')
for row in reader:
for key, val in row.iteritems():
print type(key), key,':',type(val),val
print type(row), row
if row['OBJECTID'] is not '':
, которые дают эту:
<type 'unicode'> Type de fenêtre_Cadre : <type 'unicode'> 7
<type 'unicode'> Liste des fenêtres_Hauteur : <type 'unicode'> 3.29
<type 'unicode'> Type de fenêtre_uniqueid : <type 'unicode'> uid-100
<type 'unicode'> Liste des fenêtres_Nom : <type 'unicode'> f1
<type 'unicode'> OBJECTID : <type 'unicode'> 3760
<type 'unicode'> Type de fenêtre_Intercalaire : <type 'unicode'> 1
<type 'unicode'> Liste des fenêtres_Ombrage1 : <type 'unicode'> uid-201
<type 'unicode'> Liste des fenêtres_Largeur : <type 'unicode'> 1.55
<type 'unicode'> Liste des fenêtres_Part cadre : <type 'unicode'> 20
<type 'unicode'> Liste des fenêtres_Type de fenêtre : <type 'unicode'> uid-100
<type 'unicode'> Type de fenêtre_Nom : <type 'unicode'> Fenetre 2006-2010
<type 'unicode'> Liste des fenêtres_CheckDelete : <type 'unicode'>
<type 'unicode'> Liste des fenêtres_Nb vantaux : <type 'unicode'> 2
<type 'unicode'> Type de fenêtre_CheckDelete : <type 'unicode'>
<type 'unicode'> Type de fenêtre_vitrage : <type 'unicode'> 4
<type 'unicode'> Liste des fenêtres_Façade : <type 'unicode'> uid-001-AW1
<type 'unicode'> Liste des fenêtres_Ombrage2 : <type 'unicode'>
<type 'unicode'> Liste des fenêtres_Nombre : <type 'unicode'> 1
<type 'dict'> {u'Type de fen\xeatre_Cadre': u'7', u'Liste des fen\xeatres_Hauteur': u'3.29', u'Type de fen\xeatre_uniqueid': u'uid-100', u'Liste des fen\xeatres_Nom': u'f1', u'\ufeffOBJECTID': u'3760', u'Type de fen\xeatre_Intercalaire': u'1', u'Liste des fen\xeatres_Ombrage1': u'uid-201', u'Liste des fen\xeatres_Largeur': u'1.55', u'Liste des fen\xeatres_Part cadre': u'20', u'Liste des fen\xeatres_Type de fen\xeatre': u'uid-100', u'Type de fen\xeatre_Nom': u'Fenetre 2006-2010', u'Liste des fen\xeatres_CheckDelete': u'', u'Liste des fen\xeatres_Nb vantaux': u'2', u'Type de fen\xeatre_CheckDelete': u'', u'Type de fen\xeatre_vitrage': u'4', u'Liste des fen\xeatres_Fa\xe7ade': u'uid-001-AW1', u'Liste des fen\xeatres_Ombrage2': u'', u'Liste des fen\xeatres_Nombre': u'1'}
Traceback (most recent call last):
File "./oba.py", line 120, in <module>
sys.exit(main())
File "./oba.py", line 115, in main
readCSV(f,out)
File "./oba.py", line 37, in readCSV
if row['OBJECTID'] is not '':
KeyError: 'OBJECTID'
который теперь делает меня запутать, как к тому, что происходит за кулисами с кодировкой:
- Как исправить это, не ища «\ ufeffOBJECTID» в моем dict?
- Почему в моей второй попытке питон признает, что он считывает данные utf-8 (unicode) в строке, но все же отображает его неправильно, когда я печатаю строку как dict?
- что проблема с печатью/хранением unicode dicts в python? Ожидается ли такое поведение для любого контейнера?
Может ли кто-нибудь с более глубоким пониманием кодирования дать мне некоторую информацию о том, что происходит за кулисами здесь?
Спасибо.
EDIT: также стоит отметить, что в заголовке файла я объявил кодировку как utf-8. (Т.е. "# - - кодирование: UTF-8 - -"), и я бегу v2.7.6
любой шанс, что вы могли бы поставить ссылку на тест CSV, который вызывает эти ошибки? – wilfo
уверен. [this] (https://dl.dropboxusercontent.com/u/105505396/Fenetre.csv) - это файл, который я использую в примере выше. – bny
. Тест 'some_object is not ''' очень опасен, потому что нет гарантии, что каждая пустая строка является тем же самым объектом. Таким образом, этот тест может завершиться неудачно, даже если 'some_object' является пустой строкой. Или другими словами: если он работает так, как вы его написали, он более или менее «случайно» - деталь реализации. – BlackJack