15
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
4

3 回答 3

18

不幸的是,3to2使用了io.open()调用而不是内置的 Python 2open()函数。这会以文本模式打开文件,这与 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模块示例部分包含的代码可以在编写之前从 Unicode 进行编码变得更容易一些。

于 2013-08-26T17:19:36.780 回答
1

由于换行参数,Martijn Pieters 使用 'w' 或 'wb' 的解决方案似乎不起作用。我个人得到一个ValueError。

ValueError: binary mode doesn't take a newline argument

我不太明白,我希望io忽略它而不是引发异常。在 python 2 和 3 上对我都有效的唯一解决方案是:

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

打开大量文件时可能会变得非常繁重的解决方案。Martijn 解决方案在这方面更清洁,只要它可以工作!

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

import sys
import io

def open_csv_rb(my_file):
    if sys.version_info[0] < 3:
        return io.open(my_file, 'rb')
    else:
        return io.open(my_file, 'r', encoding='utf8')

def open_csv_wb(my_file):
    if sys.version_info[0] < 3:
        return io.open(my_file, 'wb')
    else:
        return io.open(my_file, 'w', newline='', encoding='utf8')
于 2018-07-11T12:27:06.863 回答
-1

我对 open() 和 csv 有同样的问题。有朋友给了我解决办法,就是用open_output()代替open()。open_output() 默认为“wb”而不是文本。

于 2017-12-19T17:37:53.863 回答