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

Posted

技术标签:

【中文标题】Python 2 和 3 csv 模块文本二进制模式向后兼容【英文标题】:Python 2 and 3 csv module text-binary mode backwards compatibility 【发布时间】:2019-10-05 22:56:36 【问题描述】:

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

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

import sys
w = 'w'
if sys.version_info[0] < 3:
   w = 'wb'
# Where needed
outfile=open('./test.csv',w)

不是很好,如果我使用 Python 2.7 和 w 如果我使用 Python 3.x,是否有更好的解决方案可以在“wb”中打开文件?为了澄清,我必须在 Python 2.7 中使用 wb,否则,每次向文件添加新行时都会有一个空行。

【问题讨论】:

【参考方案1】:

当在 python 3 上打开要与模块 csv 一起使用的文件时,总是应该在 open 语句中添加 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 中跳过它,你会在窗口中得到形状不正确的 csv 输出,其中包含额外的空行.

见csv.writer (python 3):

如果 csvfile 是一个文件对象,它应该用newline='' 打开。如果未指定newline='',则嵌入在引用字段中的换行符将不会被正确解释,并且在使用\r\n linendings 的平台上,将添加额外的\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 中不存在。要解决此问题,您必须 wrap/monkypath open(..) 包括上下文管理。

【讨论】:

谢谢帕特里克,是的,这就是我遇到这个问题的原因,我想解决它,是的,我使用withstatements,我没有为了简洁而放入工作示例。我认为您的回答并不能回答我的问题,这是错误的,因为您编写的代码在python2.7中不起作用。 您链接的问题中没有任何地方任何提到newline="" - 有一条评论提到它的接受答案。链接的问题是关于 'wb' vs 'w' 和 str vs bytelike 对象(就像你的一样) - 不是关于省略 newline="" 像 f.e. 这样的问题。这里:https://***.com/questions/3348460/csv-file-written-with-python-has-blank-lines-between-each-row。稍后将删除此答案,因为它似乎与您的问题无关。 我没有说任何关于newline 的事情我只是测试了你的解决方案,但它并没有解决我的问题,现在你的编辑至少回答了我的问题,所以我已经投票了,我不想粗鲁,只是试图解决问题并提供反馈

以上是关于Python 2 和 3 csv 模块文本二进制模式向后兼容的主要内容,如果未能解决你的问题,请参考以下文章

Python 3.x标准模块库目录

Python 3.x标准模块库目录

Python处理CSV,Excel,PDF和图片

python读写csv文件

python处理.csv文件

python处理.csv文件