我们终于要将一个应用程序升级到Python 3。
我们需要升级的一件事是使用正常换行符重写CSV文件。
原始(Python 2)代码如下:
import csv
IN_PATH = 'in.csv'
OUT_PATH = 'out.csv'
# Opens the original file in 'text mode' (which has no effect on Python 2)
# and with 'universal newlines',
# meaning \r, \n, and \r\n all get treated as line separators.
with open(IN_PATH, 'rU') as in_csv:
with open(OUT_PATH, 'w') as out_csv:
csv_reader = csv.reader(in_csv)
csv_writer = csv.writer(out_csv)
for tupl in csv_reader:
csv_writer.writerow(tupl)
这些CSV文件由用户提供。这意味着:
- 我们无法控制它们使用哪种换行符,因此我们需要处理所有的换行符。
- 在此阶段,我们不知道文件的编码方式。
因为我们不知道编码方式,所以无法将字节流解码为文本。
为了使其在Python 3上工作,首先我们改用io.open()
,它与py3的open()
大多兼容。现在我们不能再使用“文本模式”了,因为在Python 3上需要对字节串进行解码,而我们不知道编码方式。
但是,使用“二进制模式”意味着我们不能再使用通用换行符,因为那只在文本模式下可用。
# Opens the original file in 'binary mode'
# (because we don't know the encoding, so we can't decode it)
# FIXME: How to get universal newline support?
with io.open(IN_PATH, 'rb') as in_csv:
with io.open(OUT_PATH, 'wb') as out_csv:
请注意,虽然在Python 3中不再支持
U
模式字符,但它默认在文本模式下使用通用换行符。它似乎没有任何方法在二进制模式下使用通用换行符。我们如何在Python 3中使此代码工作?
plain open
相当于 Python 2 中的io.open
,因此使用io.open
可以实现兼容性,这就是我选择使用它的原因。 - craigdscsv
无法处理字节。 - MisterMiyagi