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(..)
包括上下文管理。
【讨论】:
谢谢帕特里克,是的,这就是我遇到这个问题的原因,我想解决它,是的,我使用with
statements,我没有为了简洁而放入工作示例。我认为您的回答并不能回答我的问题,这是错误的,因为您编写的代码在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 模块文本二进制模式向后兼容的主要内容,如果未能解决你的问题,请参考以下文章