在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件

Posted

技术标签:

【中文标题】在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件【英文标题】:Writing a .CSV file in Python that works for both Python 2.7+ and Python 3.3+ in Windows 【发布时间】:2015-07-02 15:58:58 【问题描述】:

编辑:我把它放在标题中,但我意识到我没有在正文中提到它。这似乎是特定于 Windows 的。

我很难在适用于 Python 2.7 和 3.3 的脚本中使用 csv Python 模块编写输出。

第一次尝试在 Python 2.7 中按预期工作:

with open('test.csv', 'wb') as csv_file:
    writer = csv.DictWriter(csv_file, ['header1', 'header2'])
    writer.writeheader()
    for item in items:
        writer.writerow(item)

然而,当同样的事情在 Python 3.3 中运行时,你会得到:

TypeError: 'str' does not support the buffer interface

所以我将'wb' 更改为'wt' 并且它运行了,但现在我在文件中每隔一行有一个额外的空白行。

为了解决这个问题,我改变了:

with open('test.csv', 'wt') as csv_file:

到:

with open('test.csv', 'wt', newline='') as csv_file:

但现在,它破坏了 Python 2.7:

TypeError: 'newline' is an invalid keyword argument for this function

我知道我可以这样做:

try:
    with open('test.csv', 'wt', newline='') as csv_file:
        writer = csv.DictWriter(csv_file, ['header1', 'header2'])
        writer.writeheader()
        for item in items:
            writer.writerow(item)
except TypeError:
    with open('test.csv', 'wb') as csv_file:
        writer = csv.DictWriter(csv_file, ['header1', 'header2'])
        writer.writeheader()
        for item in items:
            writer.writerow(item)

但是,这有一些严重的重复。

有人有更清洁的方法吗?

编辑:测试数据很简单,没有换行符或任何东西:

items = ['header1': 'value', 'header2': 'value2',
         'header1': 'blah1', 'header2': 'blah2']

【问题讨论】:

你不能用'w'代替'wb''wt'吗? 当您在 Python 2 中运行脚本时,您的 items 列表中的字符串是否为 unicode 字符串?这些值是否总是 ASCII,或者它们是否包含需要编码的额外字符?即使您能够在两个版本的 Python 下运行相同的代码,也可能不会得到相同的结果! @Blckknght - 我将测试数据添加到问题的底部。它只是 ASCII 文本。 【参考方案1】:

我尝试了几种方法。据我所知,简单地使用'w' 可能是一个解决方案:

with open('test.csv', 'w') as csv_file:
    writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n')
    # write something

【讨论】:

如果我这样做,我仍然每隔一行得到空行。您是否在 Windows 或其他设备上尝试过此操作? @Tamerz 您获得了额外的新行,因为您的数据中有额外的新行....strip() 可能是您所需要的。 @Tamerz 我尝试了一些假数据,结果很好。所以我认为你的数据也有问题。 wwt 相同 @skyline75489 - 将测试数据添加到原始问题。你可以看到它只是一个字典中的几个字符串。【参考方案2】:

这是一个更简单的通用方法:

import sys

if sys.version_info[0] == 2:  # Not named on 2.6
    access = 'wb'
    kwargs = 
else:
    access = 'wt'
    kwargs = 'newline':''

with open('test.csv', access, **kwargs) as csv_file:
    writer = csv.DictWriter(csv_file, ['header1', 'header2'])
    writer.writeheader()
    for item in items:
        writer.writerow(item)

这里的原则是不要试图与 Python 2 和 3 之间的差异作斗争,而是要有条件代码。没有这种测试,你只能写这么多代码,迟早你要测试 Python 版本。

【讨论】:

我认为让**kwargs 参与其中可能是一个很好的解决方案。它仍然不漂亮,但比我拥有的所有副本要好得多。这绝对适用于我的场景。谢谢。 我选择了@skyline75489 给出的答案,但我仍然喜欢这个以备将来使用。有时我确实需要这样做,但不知道最好的方法。 @Tamerz:查看my answer 类似的问题。它适用于两个版本的 Python 并处理打开文件以进行读取和写入(加上。如open(),如果未明确指定,则默认为读取模式)。它也不需要使用全局变量。

以上是关于在 Python 中编写适用于 Windows 中的 Python 2.7+ 和 Python 3.3+ 的 .CSV 文件的主要内容,如果未能解决你的问题,请参考以下文章

在 python 中,如何将 1 个或多个文件作为具有绝对路径的参数拖放到我的脚本中? (适用于 windows、linux 和 mac)

用python编写程序?

适用于 Python 3x 的 Windows 7“选择默认程序”

适用于 Windows Mobile 的简单 ANPR

无法在适用于 Windows 的 Python 3.7 上安装 win32core

用Python编写程序