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

Posted

技术标签:

【中文标题】2.7 CSV 模块想要 unicode,但不想要 unicode【英文标题】:2.7 CSV module wants unicode, but doesn't want unicode 【发布时间】:2013-08-29 05:51:36 【问题描述】:
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,我会得到 ​​p>

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

【问题讨论】:

您只查看异常;删除 TypeError 并查看完整的回溯。 Python 2.7 中的 csv 模块被记录为支持 unicode。 什么是csvfile_?它是使用iocodecs 模块打开的自动编码Unicode 的打开文件对象吗?如果是这样,那么需要 Unicode 的是 那个 文件对象,而不是 CSV 模块。请向我们展示打开文件对象的代码。 open是从哪里导入的? 内置 open() 函数在 Python 2 上不接受 newline 参数。 试试 unicodecsv。它用 unicode 包装 CSV。 【参考方案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')

【讨论】:

【参考方案2】:

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

【讨论】:

【参考方案3】:

不幸的是,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 编码更容易一些。

【讨论】:

我正在尝试编写一个 CSV 处理程序,它应该与 Python 2 或 Python 3 一起运行,我发现这个答案(通过搜索引擎找到)很有帮助。我很惊讶成为第一个支持它的用户。 会不会是第一次sn-p错过了from future.builtins import open?我认为newline 没有在 Python 2 中打开。 @moose:这就是答案的重点;另请参阅有关该问题的 cmets。导入为from io import openfuture_builtins 不包括 open。我提供了使代码3to2 兼容的选项。 @moose: 换句话说:在 Python 3 中,open() 调用没有导入语句;是 3to2 工具可以添加它。

以上是关于2.7 CSV 模块想要 unicode,但不想要 unicode的主要内容,如果未能解决你的问题,请参考以下文章

Jquery将表格导出到csv隐藏表格单元格

将 Unicode 文本文件导入 netezza 表

CSV列表的书写在Python 2.7中不起作用

在 Python 2.7 中运行 MySQL 以将 CSV 加载到 MySQL -

java将英文字母转换为unicode [关闭]

使用 pandas 或其他 python 模块读取特定列