【问题标题】:Python 2 and 3 csv module text-binary mode backwards compatibilityPython 2 和 3 csv 模块文本二进制模式向后兼容
【发布时间】: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,否则,每次向文件添加新行时都会有一个空行。

【问题讨论】:

    标签: python python-3.x python-2.7 csv backwards-compatibility


    【解决方案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://stackoverflow.com/questions/3348460/csv-file-written-with-python-has-blank-lines-between-each-row。稍后将删除此答案,因为它似乎与您的问题无关。
    • 我没有说任何关于newline 的事情我只是测试了你的解决方案,但它并没有解决我的问题,现在你的编辑至少回答了我的问题,所以我已经投票了,我不想粗鲁,只是试图解决问题并提供反馈
    猜你喜欢
    • 2010-09-24
    • 2020-04-10
    • 1970-01-01
    • 2014-07-12
    • 2018-12-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多