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

问题描述 投票:0回答:2

我想创建一个与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'

当我使用此代码修复它时:

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 python-3.x python-2.7 csv backwards-compatibility
2个回答
3
投票

python 3
上打开要与模块 csv 一起使用的文件时,您 always 应添加
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中跳过它,你会在Windows上得到畸形的csv输出,其中有额外的空行。

参见 csv.writer (python 3):

如果 csvfile 是文件对象,则应使用

newline=''
打开它。如果未指定
newline=''
,则嵌入在引用字段中的换行符将无法正确解释,并且在使用
\r\n
的平台上,将添加额外的
\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

问题是 parameter

newline
在 python 2 中不存在。要解决这个问题,你必须包含 contextmanaging 的wrapp/monkypath
open(..)


0
投票

这与帕特里克·阿特纳(Patrick Artner)的建议没有什么不同,但可能为参数分配提供更大的灵活性:

import sys
params = {"mode": 'w', "newline": ''} # or any other default parameters
if sys.version_info[0] < 3:
   params = {"mode": 'wb'}
# Where needed
outfile = open('./test.csv', **params)
© www.soinside.com 2019 - 2024. All rights reserved.