1、背景
Python open()函数里面的newline参数不怎么理解,查阅了蛮多资料,最终我看到了简书上的这篇文章。
光看也看不明白,于是我便进行了如下实验。
2、实验
2.1、写文件、读文件都带上newline=''
# 调用csv模块。
import csv
# 以只写模式打开文件test01.csv文件,若文件不存在,则新建;文件存在,则覆盖。
with open('test01.csv','w',newline='') as file:
# writer()函数返回一个 writer 对象,该对象负责将用户的数据在给定的文件类对象上转换为带分隔符的字符串。
writer=csv.writer(file)
# csv writer.writerow(row)将row 形参写入到 writer 的文件对象。
writer.writerow('a')
writer.writerow('b')
# 以只读的方式打开test01.csv文件。
with open('test01.csv','r',newline='') as file:
# read()方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
content=file.read()
# 打印内容。
print(content)
运行结果:
添加断点,启动调试,可以看到变量content的值为'a\r\nb\r\n'。
2.2、写文件带上参数newline='',读文件不带参数
# 调用csv模块。
import csv
# 以只写模式打开文件test02.csv文件,若文件不存在,则新建;文件存在,则覆盖。
with open('test02.csv','w',newline='') as file:
# writer()函数返回一个 writer 对象,该对象负责将用户的数据在给定的文件类对象上转换为带分隔符的字符串。
writer=csv.writer(file)
# csv writer.writerow(row)将row 形参写入到 writer 的文件对象。
writer.writerow('a')
writer.writerow('b')
# 以只读的方式打开test02.csv文件。
with open('test02.csv','r') as file:
# read()方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
content=file.read()
# 打印内容。
print(content)
运行结果:
添加断点,启动调试,可以看到变量content的值为'a\nb\n'。
2.3、写文件不带参数,读文件带参数newline=''
# 调用csv模块。
import csv
# 以只写模式打开文件test03.csv文件,若文件不存在,则新建;文件存在,则覆盖。
with open('test03.csv','w') as file:
# writer()函数返回一个 writer 对象,该对象负责将用户的数据在给定的文件类对象上转换为带分隔符的字符串。
writer=csv.writer(file)
# csv writer.writerow(row)将row 形参写入到 writer 的文件对象。
writer.writerow('a')
writer.writerow('b')
# 以只读的方式打开test03.csv文件。
with open('test03.csv','r',newline='') as file:
# read()方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
content=file.read()
# 打印内容。
print(content)
运行结果:
添加断点,启动调试,可以看到变量content的值为'a\r\r\nb\r\r\n'。
2.4、写文件、读文件都不带参数newline=''
# 调用csv模块。
import csv
# 以只写模式打开文件test04.csv文件,若文件不存在,则新建;文件存在,则覆盖。
with open('test04.csv','w') as file:
# writer()函数返回一个 writer 对象,该对象负责将用户的数据在给定的文件类对象上转换为带分隔符的字符串。
writer=csv.writer(file)
# csv writer.writerow(row)将row 形参写入到 writer 的文件对象。
writer.writerow('a')
writer.writerow('b')
# 以只读的方式打开test04.csv文件。
with open('test04.csv','r') as file:
# read()方法用于从文件读取指定的字节数,如果未给定或为负则读取所有。
content=file.read()
# 打印内容。
print(content)
运行结果:
添加断点,启动调试,可以看到变量content的值为'a\n\nb\n\n'。
3、说明
下面4张图片选自Python官方文档。
图一
图二
图三
图四
序号 | 说明 | 结果 |
---|---|---|
实验一 | 写文件、读文件都带上newline='' | a\r\nb\r\n |
实验二 | 写文件带上参数newline='',读文件不带参数 | a\nb\n |
实验三 | 写文件不带参数,读文件带参数newline='' | a\r\r\nb\r\r\n |
实验四 | 写文件、读文件都不带参数newline='' | a\n\nb\n\n |
由图三、图四可知:
- 如果写文件时,未指定newline参数,则将'\n'转换为系统默认行分隔符,又由图二可知,Windows系统默认的行分隔符为'\r\n'。即写文件时,未指定newline参数,则'\n'会转换为'\r\n'。【注:第二部分实验的操作系统为Windows】
- 如果读文件时,未指定newline参数,则'\r'、'\r\n'都会转换为'\n'。
- 写文件、读文件时,指定了newline='',不会发生转换。
由实验一的结果可推断出:
- csv模块中的writerow()方法在写文件时会加入'\r\n'作为换行符。【写文件、读文件都指定了newline='',不会发生转换,因此可以推断出writerow()方法会在写文件时加入'\r\n'作为换行符。】
实验一:
csv模块中的writerow()方法在写文件时会加入'\r\n'作为换行符。写文件的时候,指定newline='',因此写入文件的数据不会发生替换,即写入文件的数据为'a\r\nb\r\n';与此同时,读文件的时候,指定了newline='',因此读出的数据不会发生转换。因此结果为'a\r\nb\r\n'。
实验二:
csv模块中的writerow()方法在写文件时会加入'\r\n'作为换行符。写文件的时候,指定newline='',因此写入文件的数据不会发生替换,即写入文件的数据为'a\r\nb\r\n';读文件的时候,未指定newline='',因此'\r'、'\r\n'都会转换为'\n',即文件中的'\r\n'会被替换'\n'放入缓冲区。因此结果为'a\nb\n'。
实验三:
csv模块中的writerow()方法在写文件时会加入'\r\n'作为换行符。写文件的时候,未指定newline='',此时'\n'会转换为'\r\n',即写入文件的数据由'a\r\nb\r\n'转为'a\r\r\nb\r\r\n'。读文件的时候,指定了newline='',因此读出的数据不会发生转换。因此结果为'a\r\r\nb\r\r\n'。
实验四:
csv模块中的writerow()方法在写文件时会加入'\r\n'作为换行符。写文件的时候,未指定newline='',此时'\n'会转换为'\r\n',即写入文件的数据由'a\r\nb\r\n'转为'a\r\r\nb\r\r\n'。读文件的时候,未指定newline='','\r'、'\r\n'都会转换为'\n',因此'a\r\r\nb\r\r\n'中的尾部'\r\n'被替换成'\n';第一个'\r'替换为'\n',因此结果为'a\n\nb\n\n'。