【发布时间】:2019-03-13 17:03:53
【问题描述】:
不久前,我向question 询问了有关处理带有特殊字符的 .csv 文件的导入问题。当时我有兴趣解决 90% 的问题,但现在我又回来解决最后 10% 的问题了。
基本上和以前一样设置:
- 许多输入文件
- 所有.csv
- 新:现在我想在某些输入中保留特殊字符。但是,我无法控制所有输入文件的格式,因此我需要处理混合文件。当我想要使用不同的编码格式时,我尝试的解决方案是传递一个关键字参数。
代码如下:
import csv
import unicodecsv
#<Lots of other declarations and initialization>
def _csv_dict(self, file,index_field, ScrubMe, **kwargs):
#some irrelevant initialization stuff here.
if 'formatting' in kwargs:
formatting = kwargs['formatting']
else:
formatting = None #cp1252 is OS default
with open(file, encoding=formatting, errors='ignore') as f: #newline = '',
if formatting == None:
reader = csv.DictReader(f, dialect = 'excel')
else: #assume for now UTF-8 is the only other supported format
reader = unicodecsv.DictReader(f, dialect = csv.excel)
for line in reader:
<do some stuff - it's mostly building dictionaries, but I
generally edit the data to only keep the stuff I care about and do a little
data transformation to standard formats >
上面的结果是,如果我传递一个保存为本地编解码器的 .CSV 的 Excel 文件,则导入工作。但是,调用包含格式='utf-8' 关键字 arg 的 unicodecsv 文件会崩溃
错误消息表明我在沿线某处传递了错误类型的对象。这发生在我第一次尝试从 UTF-8 文件中读取一行时
File
"C:\Users\<me>\AppData\Local\Programs\Python\Python37\lib\site-
packages\unicodecsv\py3.py", line 51, in <genexpr>
f = (bs.decode(encoding, errors=errors) for bs in f)
AttributeError: 'str' object has no attribute 'decode'
根据我的阅读,UTF-8 实际上是制表符分隔而不是逗号分隔,但我“认为”它应该以相同的方式工作。
我觉得我可能搞砸了一些非常简单的事情,但我已经花了足够多的时间来寻找似乎适合寻求帮助的时间。提前感谢您的任何建议。
【问题讨论】:
-
嗯,我进步了一点。错误消息中的 bs.decode() 显然不是关于 Python 能够解码我要求它执行的 BS。它希望我以二进制模式打开文件。我仍然没有工作。我遇到了一个关键错误。文件顶部似乎有一些标题信息,而 unicode csvReader 处理不正确。
-
标头原来是一个 UTF-16 字节顺序标记。这让我很困惑,因为我要求 Excel 保存为 UTF-8 .csv。我尝试只读取两个字节的标头,但它显然希望有一个标头,并且出现意外字节的错误。我尝试使用 UTF-16 编码设置为阅读器打开文本文件。这使我所有的文字都变得难以阅读。到目前为止,最接近正确的是打开是否打开(文件,'rb')并且阅读器上的编码是'utf-8',但它会破坏我的第一个键与 BOM。
-
在 Python 3 中不需要
unicodecsv。std-libcsv模块在此处使用 (Unicode) 字符串。 -
我的源文件是带有“另存为 .csv UTF-8”的 Excel。也许我做错了什么,但如果我使用标准的 .csv,它会因为 BOM 而破坏第一个键。我敢打赌,如果数据是从文本编辑器而不是 Excel 保存的,它会起作用。具有讽刺意味的是,Excel 并不能很好地重新摄取这些数据。
-
听到 Excel 在正确解码文本数据方面表现不佳,我不会感到惊讶。但是,如果您使用 Python 3,这与您不需要(甚至不应该)使用
unicodecsv包这一事实完全无关。使用正确的编码以文本模式打开文件,一切都应该顺利通过 std-libcsv模块(前提是您没有损坏的数据)。
标签: python python-3.x csv file-io utf-8