Python 2 和 3 csv 模块文本二进制模式向后兼容



我想创建一个与Python 2.7-3.6兼容的代码,我正在尝试解决csv模块的问题,最初我在Python 2.7中使用了outfile=open('./test.csv','wb'),现在我必须使用outfile=open('./test.csv','w'),就像在这个问题中一样,否则我会产生TypeError: a bytes-like object is required, not 'str'.

A 我使用此代码修复它的那一刻:

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,否则,每次向文件添加新行时,我都会有一个空行。

python 3上打开要与模块csv一起使用的文件时,您应该始终newline=""open 语句添加:

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 输出,其中包含额外的空行。

参见csv.writer(python 3):

如果csvfile是文件对象,则应使用newline=''打开它。 如果未指定newline='',则无法正确解释嵌入在引号字段中的换行符,并且在写入时使用rn行尾的平台上,将添加额外的r。指定newline=''应该始终是安全的,因为csv 模块执行自己的(通用)换行符处理。


您还应该使用上下文管理with

with open("somefile.txt", mode) as f:  # works in 2 and 3
pass  # do something with f

关闭文件句柄,即使您遇到某种异常。这是 python 2 安全的 - 请参阅文件对象的方法:

处理文件对象时使用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

问题是 python 2 中不存在newline参数。要解决此问题,您必须包装/monkypathopen(..)包括上下文管理。

最新更新