在 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 我尝试了一些假数据,结果很好。所以我认为你的数据也有问题。
w
与wt
相同
@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 3x 的 Windows 7“选择默认程序”