<p>您的输入数据在<em>的每一行中都包含<a href="https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8" rel="nofollow noreferrer">UTF-8 BOM sequences</a>。不管生成这个文件的是什么,它似乎一直在使用<code>utf-8-sig</code>编解码器或非Python等价物一次添加一行数据。BOM(如果使用的话)应该是文件中的第一个字符,<em>不能在其他任何地方使用。您的数据已损坏,如果您可以在源代码处修复此问题,请这样做。在</p>
<p>但是,有一种方法可以在您阅读时修复此问题。<code>csv</code>模块读取的“file”可以是任何在迭代时生成行的内容。首先使用生成器过滤文件行:</p>
<pre><code>from codecs import BOM_UTF8
def bom_filter(lines):
for line in lines:
if line.startswith(BOM_UTF8):
line = line[len(BOM_UTF8):]
yield line
</code></pre>
<p>然后,在将文件传递给<code>DictReader()</code>对象之前,先通过过滤器:</p>
^{pr2}$
<p>演示:</p>
<pre><code>>>> from io import BytesIO
>>> import csv
>>> from codecs import BOM_UTF8
>>> def bom_filter(lines):
... for line in lines:
... if line.startswith(BOM_UTF8):
... line = line[len(BOM_UTF8):]
... yield line
...
>>> demofile = BytesIO('''\
... \xef\xbb\xbfid,name,age,height,weight
... \xef\xbb\xbf1,x,12,11,124
... \xef\xbb\xbf2,y,13,23,432
... \xef\xbb\xbf3,z,14,43,1435
... ''')
>>> ipFile = csv.DictReader(bom_filter(demofile))
>>> for row in ipFile:
... print row
...
{'age': '12', 'height': '11', 'id': '1', 'weight': '124', 'name': 'x'}
{'age': '13', 'height': '23', 'id': '2', 'weight': '432', 'name': 'y'}
{'age': '14', 'height': '43', 'id': '3', 'weight': '1435', 'name': 'z'}
</code></pre>
<p>在python3中,<code>csv</code>模块接受Unicode字符串输入(与bytestrings相反,因此现在需要查找解码结果,即U+FEFF零宽度空间码位。要使代码在任何一个Python版本上都能正常工作,您必须在行首替换要测试的内容:</p>
<pre><code>import sys
to_filter = u'\ufeff'
if sys.version_info < (3,):
to_filter = to_filter.encode('utf8')
def bom_filter(lines):
for line in lines:
if line.startswith(to_filter):
line = line[len(to_filter):]
yield line
</code></pre>