2.7 CSV模块需要unicode,但不需要unicode

时间:2013-08-26 17:02:34

标签: python csv python-2.7 unicode error-handling

csvfile_ = open(finishedFileName+num+".csv","w",newline='')
writ = csv.writer(csvfile_, dialect='excel')
firstline = unicode(str(firstline))
try:
    writ.writerow(firstline)
except TypeError:
    print firstline
    print type(firstline)
    raise

我使用此代码获得TypeError: must be unicode, not str。打印第一行的类型时,我看到<type 'unicode'>。当我打印第一行时,我看到['project_number', 'project_location'](列表比那个更长,但它继续以那种风格。)

这个程序在python 3.3中运行良好。我用3to2将它移植过来,在我这样做时从unix切换到windows。

如何使这个程序顺利写入?

注意:根据官方文档,此版本的csv模块不支持Unicode输入,但它告诉我无论如何都要给它输入Unicode。

完全例外

Traceback (most recent call last):
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 382, in <module>
    process(marketingLogExportFileName)
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 123, in process
    writing(csvfile,modified,firstline)
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 114, in writing
    writ.writerow(firstline)
TypeError: must be unicode, not str

如果我拿出代码来制作第一行unicode,我就转而

Traceback (most recent call last):
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 382, in <module>
    process(marketingLogExportFileName)
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 123, in process
    writing(csvfile_,modified,firstline)
  File "C:\Users\urightswt\Downloads\LogModToConvert.py", line 114, in writing
    writ.writerow(firstline)
TypeError: must be unicode, not str

3 个答案:

答案 0 :(得分:15)

不幸的是,3to2使用io.open()调用而不是内置的Python 2 open()函数。这在文本模式下打开了文件,就像在Python 3上一样,需要Unicode输入。

但是, csv模块不支持Unicode数据;它肯定不会产生Unicode。

您必须在Python 2上以二进制模式打开文件:

mode = 'w'
if sys.version_info.major < 3:
    mode += 'b'
csvfile_ = open(finishedFileName + num + ".csv", mode, newline='')

或使用内置open()调用:

csvfile_ = open(finishedFileName + num + ".csv", 'wb')

无论如何你必须使用'wb'作为模式。

如果您正在尝试写出unicode数据,则必须在将数据传递给csv.writer()对象之前对该数据进行编码。 csv module examples section包括在编写之前使用Unicode进行编码的代码。

答案 1 :(得分:0)

我遇到了与open()和csv相同的问题。一位朋友给了我解决方案,即使用open_output()而不是open()。 open_output()默认为“wb”而不是文本。

答案 2 :(得分:0)

Martijn Pieters使用'w'或'wb'的解决方案似乎因换行符而无效。我个人遇到了ValueError。

@import url('https://fonts.googleapis.com/css?family=Roboto:400,700&subset=latin-ext');
body {font-family: 'Roboto', sans-serif;}

我不太了解,我希望ValueError: binary mode doesn't take a newline argument 忽略它而不是引发异常。 在python 2和python 3上都对我有用的唯一解决方案是:

io

打开许多文件时,此解决方案可能会变得非常繁琐。 Martijn解决方案在这方面更清洁,只要它能起作用!

编辑: 我认为开发需要读取/写入文件的程序包时,最干净的解决方案是创建一个小的实用程序函数,该函数可以在程序包中的任何地方调用:

if sys.version_info.major < 3:
    open(my_csv_file, 'rb')
else:
    open(my_csv_file, 'r', newline='')