在Python 2中,这段代码与我所期望的一样。
import csv
import sys
writer = csv.writer(sys.stdout)
writer.writerow([u'hello', b'world'])
它打印。
hello,world
但在Python 3中, bytes
是用前缀和引号打印的。
hello,b'world'
因为CSV是一种通用的数据交换格式,而且除了Python之外,没有其他系统知道什么是CSV。b''
是,我需要禁止这种行为。 但我还没有想好怎么做。
当然,我可以使用 str.decode
在所有 bytes
但这很不方便,而且效率很低。 我真正想要的是把字面字节写到文件中,或者把编码(例如'ascii')传给 csv.writer()
所以它知道如何解码任何 bytes
对象。
csv
在Python 3中,写文本文件并期望使用Unicode (文本)字符串。
csv
在Python 2中写入二进制文件并期望使用字节字符串,但允许使用默认的Unicode字符串隐式编码为字节字符串。ascii
编解码器。 Python 3 不允许隐式转换,所以你真的无法避免。
#!python3
import csv
import sys
writer = csv.writer(sys.stdout)
writer.writerow(['hello', b'world'.decode()])
我不认为有任何方法可以避免使用 csv
模块。在 Python 2 中,它们被隐式地转换为 ASCII。
为了使之更容易,您可以有效地将 csv.writer
或包裹对象,如下图所示,这将使过程更加方便。
import csv
class CSV_Writer(object):
def __init__(self, *args, **kwrds):
self.csv_writer = csv.writer(*args, **kwrds)
def __getattr__(self, name):
return getattr(self.csv_writer, name)
def writerow(self, row):
self.csv_writer.writerow(str(v, encoding='utf-8') if isinstance(v, bytes)
else v for v in row)
def writerows(self, rows):
for row in rows:
self.writerow(row)
with open('bytes_test.csv', 'w', newline='') as file:
writer = CSV_Writer(file)
writer.writerow([u'hello', b'world'])