我有以下脚本来读取UTF-8 CSV:
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 de fenêtre_uniqueid : uid-100
Type de fenêtre_CheckDelete :
Type de fenêtre_Nom : Fenetre 2006-2010
Type de fenêtre_Intercalaire : 1
Liste des fenêtres_Hauteur : 3.29
OBJECTID : 3760
Liste des fenêtres_Nb vantaux : 2
Liste des fenêtres_Façade : uid-001-AW1
Type de fenêtre_Cadre : 7
Type de fenêtre_vitrage : 4
Liste des fenêtres_Part cadre : 20
Liste des fenêtres_Nom : f1
Liste des fenêtres_Nombre : 1
Liste des fenêtres_Ombrage1 : uid-201
Liste des fenêtres_Largeur : 1.55
Liste des fenêtres_Ombrage2 :
Liste des fenêtres_CheckDelete :
Liste des fenêtres_Type de fenêtre : uid-100
{'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
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'
如果查看堆栈跟踪之前的最后一行,则会看到尽管第一行中的键和值字符串的编码都正确。字典未使用正确的编码存储键/值。因此,错误。
为了解决此问题,我尝试了以下操作:
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 de fenêtre_Cadre : 7
Liste des fenêtres_Hauteur : 3.29
Type de fenêtre_uniqueid : uid-100
Liste des fenêtres_Nom : f1
OBJECTID : 3760
Type de fenêtre_Intercalaire : 1
Liste des fenêtres_Ombrage1 : uid-201
Liste des fenêtres_Largeur : 1.55
Liste des fenêtres_Part cadre : 20
Liste des fenêtres_Type de fenêtre : uid-100
Type de fenêtre_Nom : Fenetre 2006-2010
Liste des fenêtres_CheckDelete :
Liste des fenêtres_Nb vantaux : 2
Type de fenêtre_CheckDelete :
Type de fenêtre_vitrage : 4
Liste des fenêtres_Façade : uid-001-AW1
Liste des fenêtres_Ombrage2 :
Liste des fenêtres_Nombre : 1
{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
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”?
为什么在我的第二次尝试中,python承认它读取行中的utf-8(unicode)数据,但在将行作为dict打印时仍显示错误的方式?
这是在python中打印/存储unidict字典的问题吗?任何容器都应该有这种行为吗?
可以对编码有更多了解的人可以给我一些有关幕后情况的信息吗?
谢谢。
编辑:也值得一提的是,在文件头中,我已将编码声明为utf-8。(即“#--编码:utf-8--”),而我正在运行v2.7.6
解决方案
如何解决此问题而不必在字典中查找“ \ ufeffOBJECTID”?
用于utf-8-sig而不是utf-8用于解码。在解码UTF-8编码的字节字符串时,它将自动删除BOM表代码点。
为什么在我的第二次尝试中,python承认它读取行中的utf-8(unicode)数据,但在将行作为dict打印时仍显示错误的方式?
打印容器repr()在打印容器项目时使用。这样,您可以在字符串中查看实际数据。print直接在容器项目中查看其“漂亮”版本。
在python中打印/存储unidict字典是否有问题?
这不是一个问题。这只是一种显示方法。字符串中的数据是相同的。
任何容器都应该有这种行为吗?
是。
另外,请勿is用于测试空字符串。使用:
if row['OBJECTID'] != '':
或更好,因为空字符串被认为是假的:
if row['OBJECTID']: