在 Python 中编写适用于 Python 2.7+ 和 Python 3.3+ 在 Windows 中的 .CSV 文件
Writing a .CSV file in Python that works for both Python 2.7+ and Python 3.3+ in Windows
编辑:我把它放在标题中,但才意识到我没有在 body 中提到它。这似乎特定于 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'
并且它 运行s,但是现在我在文件中每隔一行就有一个额外的空白行。
为了解决这个问题,我更改了:
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'
可能是一个解决方案:
with open('test.csv', 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n')
# write something
这里有一个更简单的通用方法:
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)
这里的原则不是去拼Python2和3的区别,而是要有条件的代码。如果没有这种测试,您只能在编写代码时走这么远,迟早您将不得不测试 Python 版本。
编辑:我把它放在标题中,但才意识到我没有在 body 中提到它。这似乎特定于 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'
并且它 运行s,但是现在我在文件中每隔一行就有一个额外的空白行。
为了解决这个问题,我更改了:
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'
可能是一个解决方案:
with open('test.csv', 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=['header1', 'header2'], lineterminator='\n')
# write something
这里有一个更简单的通用方法:
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)
这里的原则不是去拼Python2和3的区别,而是要有条件的代码。如果没有这种测试,您只能在编写代码时走这么远,迟早您将不得不测试 Python 版本。