在类似字节的对象上使用csv.Sniffer

时间:2018-12-19 18:32:46

标签: python python-3.x csv

我有以下代码用来推断csv文件中的字段分隔符和行终止符:

first_line = b'132605,1\r\n'
dialect = csv.Sniffer().sniff(first_line)

从以上所述,我希望csv Sniffer能够推断出分隔符为,,行终止符为\r\n。但是,它返回以下错误:

  

TypeError:无法在类似字节的对象上使用字符串模式

解决此问题的最佳方法是什么?

请注意,我之所以以b模式打开它是为了让我可以看到所有字符,例如:

>>> open('10_no_headers.csv','r+b').read()[:10]
b'132605,1\r\n'

>>> open('10_no_headers.csv','r').read()[:10]
'132605,1\n1' # doesn't show the \r

2 个答案:

答案 0 :(得分:2)

以“ r”模式打开并提供newline=''

import csv

with open('foo.txt', 'w') as f:
    f.write('132605,1\r\n')

with open('foo.txt', 'r') as f:
    print(repr(next(f)))

with open('foo.txt', 'rb') as f:
    print(repr(next(f)))

with open('foo.txt', 'r', newline='') as f:
    line = next(f)
    dialect = csv.Sniffer().sniff(line)
    print(repr(line))
    print ('FIELED:', repr(dialect.delimiter), 'LINE:', repr(dialect.lineterminator))

输出

'132605,1\n'
b'132605,1\r\n'
'132605,1\r\n'
FIELED: ',' LINE: '\r\n'

from the docs

  

换行符控制通用换行符模式的工作方式(仅适用于文本模式)。可以是“无”,“”,“ \ n”,“ \ r”和“ \ r \ n”。其工作原理如下:

     
      
  • 从流中读取输入时,如果换行符为None,则启用通用换行符模式。输入中的行可以以'\ n','\ r'或'\ r \ n'结尾,在返回给调用者之前,这些行会转换为'\ n'。 如果为”,则表示启用了通用换行模式,但行结尾未翻译就返回给调用方。如果具有其他任何合法值,则输入行仅以给定的字符串终止,并且该行的结尾未经翻译就返回给调用方。
  •   
  • 将输出写入流时,如果换行符为None,则写入的所有\ n字符都将转换为系统默认的行分隔符os.linesep。如果换行符是''或'\ n',则不会进行翻译。如果换行符是其他任何合法值,则所有写入的'\ n'字符都将转换为给定的字符串。
  •   

答案 1 :(得分:0)

一个可能的选择是在将其传递到Sniffer之前对其进行解码。例如:

import csv

first_line = b'132605,1\r\n'
dialect = csv.Sniffer().sniff(first_line.decode('utf-8'))

print ('FIELED:', repr(dialect.delimiter), 'LINE:', repr(dialect.lineterminator))
FIELED: ',' LINE: '\r\n'