我想创建一个与Python 2.7-3.6兼容的代码,我试图解决csv模块的问题,最初我在Python 2.7中使用0[{Last=...,Foo=...}]
1[{Last=...,Foo=...}]
2[{Last=...,Foo=...}]
3[{Last=...,Foo=...}]
4[{Last=...,Foo=...}]
5[{Last=...,Foo=...}]
,现在我必须使用outfile=open('./test.csv','wb')
like in this question,否则会导致
outfile=open('./test.csv','w')
。
我正在使用以下代码对其进行修复:
TypeError: a bytes-like object is required, not 'str'
不太好,如果使用Python 2.7并在import sys
w = 'w'
if sys.version_info[0] < 3:
w = 'wb'
# Where needed
outfile=open('./test.csv',w)
中使用Python 3.x,是否有更好的解决方案在'wb'中打开文件?为了澄清我必须在Python 2.7中使用w
,因为否则,每次向文件中添加新行时,我都会有一个空白行。
答案 0 :(得分:2)
在 python 3 上打开要与模块csv
一起使用的文件时,总是应在打开语句中添加newline=""
:
import sys
mode = 'w'
if sys.version_info[0] < 3:
mode = 'wb'
# python 3 write
with open("somefile.txt", mode, newline="") as f:
pass # do something with f
newline
参数在python 2中不存在-但是,如果在 python 3 中跳过该参数,则在带有附加空行的Windows上将得到变形的csv输出在里面。
如果 csvfile 是文件对象,则应使用
newline=''
打开它。如果未指定newline=''
,则不会正确解释加引号的字段中嵌入的换行符,并且在使用\r\n
linding编写的平台上,将添加额外的\r
。指定newline=''
应该总是安全的,因为 csv模块会执行自己的(通用)换行符处理。
您还应该使用上下文管理with
:
with open("somefile.txt", mode) as f: # works in 2 and 3
pass # do something with f
即使遇到某种异常也可以关闭文件句柄。这是python 2安全的-参见Methods of file objects:
在处理文件对象时,最好使用
with
关键字。这样做的好处是,即使在执行过程中引发了异常,文件在其套件完成后也将正确关闭。它也比编写等效的try-finally
块要短得多。
您的解决方案-丑陋但可行:
import sys
python3 = sys.version_info[0] >= 3
if python3:
with open("somefile.txt","w",newline="") as f:
pass
else:
with open("somefile.txt","wb") as f:
pass
问题是参数 newline
在python 2中不存在。要解决此问题,您必须包装/ monkypath open(..)
,包括上下文管理。