Python 2和3 csv模块文本二进制模式向后兼容 [英] Python 2 and 3 csv module text-binary mode backwards compatibility
问题描述
我想创建一个与Python 2.7-3.6兼容的代码,我试图解决csv模块的问题,最初我在Python 2.7中使用outfile=open('./test.csv','wb')
,现在我必须使用outfile=open('./test.csv','w')
I would like to create a code which is Python 2.7-3.6 compatible I am trying to fix a problem with the csv module where initially I used outfile=open('./test.csv','wb')
in Python 2.7 now I have to use outfile=open('./test.csv','w')
like in this question otherwise I will incur in a
TypeError: a bytes-like object is required, not 'str'
.
我正在使用以下代码对其进行修复:
A the moment I am fixing it using this code:
import sys
w = 'w'
if sys.version_info[0] < 3:
w = 'wb'
# Where needed
outfile=open('./test.csv',w)
不是很好,如果使用Python 2.7,是否可以在'wb'中打开文件,如果使用Python 3.x,则可以在w
中打开文件?为了澄清我必须在Python 2.7中使用wb
,否则,每次向文件中添加新行时,我都会有一个空白行.
Not very nice, is there any better solution for opening the file in 'wb' if I am using Python 2.7 and in w
if I am using Python 3.x? To clarify I have to use wb
in Python 2.7 because otherwise, I'll have a blank line every time I add a new line to a file.
推荐答案
在 python 3 上打开要与模块csv
一起使用的文件时,总是应该添加newline=""
打开语句:
When opening files to be used with module csv
on python 3 you always should add newline=""
the the open statement:
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 中将其跳过,则会在窗口中带有其他空行的csv输出中变形
The newline
parameter does not exist in python 2 - but if you skip it in python 3 you get misshaped csv output on windows with additional empty lines in it.
请参见 csv.writer(python 3):
如果 csvfile 是文件对象,则应使用
newline=''
打开.如果未指定newline=''
,则不会正确解释加引号的字段中嵌入的换行符,并且在使用\r\n
linendings的平台上添加额外的\r
.指定newline=''
应该总是安全的,因为 csv模块会执行自己的(通用)换行符处理.
If csvfile is a file object, it should be opened with
newline=''
. Ifnewline=''
is not specified, newlines embedded inside quoted fields will not be interpreted correctly, and on platforms that use\r\n
linendings on write an extra\r
will be added. It should always be safe to specifynewline=''
, since the csv module does its own (universal) newline handling.
您还应该使用上下文管理with
:
with open("somefile.txt", mode) as f: # works in 2 and 3
pass # do something with f
使您的文件句柄关闭,即使您遇到某种异常也是如此.这是python 2安全的方法-请参见文件对象的方法:
to get your filehandles closed even if you run into some kind of exception. This is python 2 safe - see Methods of file objects:
在处理文件对象时,最好使用
with
关键字.这样做的好处是,即使在执行过程中引发了异常,文件在其套件完成后也将被正确关闭.它也比编写等效的try-finally
块短得多.
It is good practice to use the
with
keyword when dealing with file objects. This has the advantage that the file is properly closed after its suite finishes, even if an exception is raised on the way. It is also much shorter than writing equivalenttry-finally
blocks.
您的解决方案-丑陋但可行:
Your solution - ugly but works:
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(..)
,包括上下文管理.
The problem is the parameter newline
does not exist in python 2. To fix that you would have to wrap/monkypath open(..)
including the contextmanaging.
这篇关于Python 2和3 csv模块文本二进制模式向后兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!