Python 文档指定:
读取器被硬编码为将"\r"或""识别为行尾,并忽略行终止符。此行为将来可能会更改。
我写了一个简单的程序
步骤 1
with open('test.csv','wb') as f:
f.write(b'hellorrworldn!')
步骤 2
import csv
with open('test.csv','r',newline='') as f:
r = csv.reader(f)
for row in r:
print(row)
step 2
输出 :
['hello']
[]
['world']
['!']
如果我将step 1
更改为:
import csv
with open('test.csv','wb') as f:
f.write(b'hellornworldn!')
输出:
['hello']
['world']
['!']
我的问题是为什么在这种情况下空列表[]
消失了?
如果我是对的,那么在step 2
csv.reader
遇到了第一个r
并返回了它在此之前读取的内容,但是当它遇到第二个r
紧接着第一个时,它没有读取任何内容,因此返回了空列表。
但是,如果n
也是csv.reader
的终点,为什么在第二种情况下不会发生这种情况?
您正在使用内置的write
函数。
如果您查看文件,您已经看到了差异。 使用b'hellorrworldn!'
时的输出文件包含:
hello
world
!
当您使用b'hellornworldn!'
时,这将生成以下文件内容:
hello
world
!
因此,它与CSV阅读器无关。
回到你的问题:我的猜测是,在将b'hellorrworldn!'
写入文件时,rr
是单独解释的。另一方面,组合rn
被解释为一个控制字符。
我的假设基于:
一种解释文本流的方式,其中以下所有内容都被识别为结束一行:Unix行尾约定
'n'
,Windows约定'rn'
,以及旧的Macintosh约定'r'
。请参阅 PEP 278 和 PEP 3116,以及bytes.splitlines()
以了解其他用途。
与 https://docs.python.org/3/glossary.html#term-universal-newlines 相比
试用bytes.splitlines()
:
result = b'halifaxndigbynnzuerichrbernrrluganornlausanne'.splitlines()
for line in result:
print(line)
结果:
b'halifax'
b'digby'
b''
b'zuerich'
b'bern'
b''
b'lugano'
b'lausanne'
而且,如果您将rn
交换为nr
,这不是公认的行尾,那么它将写入两个新行。也就是说,b'hellonrworldn!'
将导致以下文件内容:
hello
world
!
我希望这有所帮助。干杯!
另请参阅:
- https://docs.python.org/3/library/functions.html#open
- https://docs.python.org/3/tutorial/inputoutput.html#tut-files
- https://github.com/python/cpython/blob/0093876328afa330224c9d887c18dee0b3117852/Modules/_io/fileio.c
我怀疑这是一个文档错误。CR本身是一个相当不寻常的行尾标记(我认为Unix MacOS之前使用它,以及我长大的古老的瑞典ABC80:-)),但CR + LF非常普遍,因此csv.reader将CR + LF序列解释为单个行尾是有意义的。