ChatGPT解决这个技术问题 Extra ChatGPT

如何在 CSV 文件中写入 UTF-8

我正在尝试从 PyQt4 QTableWidget 创建一个 csv 格式的文本文件。我想用 UTF-8 编码编写文本,因为它包含特殊字符。我使用以下代码:

import codecs
...
myfile = codecs.open(filename, 'w','utf-8')
...
f = result.table.item(i,c).text()
myfile.write(f+";")

它一直有效,直到单元格包含特殊字符。我也试过

myfile = open(filename, 'w')
...
f = unicode(result.table.item(i,c).text(), "utf-8")

但它也会在出现特殊字符时停止。我不知道我做错了什么。

“它也顶”?这意味着什么?你得到什么错误?你的输入是什么?
输入是一个 pyqt4 QTableWidgetItem。问题是我没有收到任何错误,因为脚本作为插件运行。
然后尝试在 QT 之外重现该问题。
找到了解决方案。我必须写 myfile.write(u"%s"&f+";")

Z
Zanon

对于 Python 3.x (docs),这非常简单。

import csv

with open('output_file_name', 'w', newline='', encoding='utf-8') as csv_file:
    writer = csv.writer(csv_file, delimiter=';')
    writer.writerow('my_utf8_string')

对于 Python 2.x,请查看 here


如果 writerow 的内容不是 utf-8 怎么办?它会起作用吗?
非常不需要第三方 pip 安装。
我没有使用文件,我使用的是 sys.stdout 那么在这种情况下内容如何是 utf8 呢?
t
the

从你的 shell 运行:

pip2 install unicodecsv

并且(与原始问题不同)假设您使用的是 Python 的内置 csv 模块,请在代码中将
import csv 转换为
import unicodecsv as csv


仅通过替换导入不起作用,我还必须在创建编写器时添加编码:writer = csv.writer(out, dialect='excel', encoding='utf-8'),并使用 open(... 创建文件处理程序,not codecs.open(...
我尝试了有关 StackOverflow 的所有建议,只有这个对我有用。
G
Gijs

使用这个包,它就可以工作:https://github.com/jdunck/python-unicodecsv


B
Bojan Bogdanovic

对我来说,Python 2 CSV 模块文档中的 UnicodeWriter 类并没有真正起作用,因为它破坏了 csv.writer.write_row() 接口。

例如:

csv_writer = csv.writer(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

有效,同时:

csv_writer = UnicodeWriter(csv_file)
row = ['The meaning', 42]
csv_writer.writerow(row)

将抛出 AttributeError: 'int' object has no attribute 'encode'

由于 UnicodeWriter 显然希望所有列值都是字符串,我们可以自己转换这些值并使用默认的 CSV 模块:

def to_utf8(lst):
    return [unicode(elem).encode('utf-8') for elem in lst]

...
csv_writer.writerow(to_utf8(row))

或者我们甚至可以对 csv_writer 进行猴子补丁以添加 write_utf8_row 函数 - 练习留给读者。


对于我们这些仍然坚持使用它的人来说,py2.x 的解决方案要简单得多。
A
Aaron Digulla

Python 文档中的示例展示了如何编写 Unicode CSV 文件:http://docs.python.org/2/library/csv.html#examples

(这里不能复制代码,因为它受版权保护)


感谢您的链接。这很有帮助。据我所知,即使您发布了链接,您也不能在此处复制粘贴代码? (+1 表示拥有版权)
@Mutant:代码不像科学论文。代码受版权保护。虽然我有 99.999% 的把握 Python 所有者不会起诉 SO 复制他们的代码,但我不想阅读他们的 lengthy license 来了解是否允许这样做。此外,偶尔提醒人们“我可以在我的显示器上看到它”!=“我可以用它做任何我想做的事情” :-)
感谢您的提醒。不幸的是,我们生活的世界变得如此(不合理)快速和粗心,信息流动的速度比人们想象的要快,它确实需要一次又一次地提醒重要的限制。感谢那 :)
文档链接是半有用的(示例更好),但这里的“版权”论点被夸大和愚蠢。 Python 是明确开源的 (v2 v3)。许可证很明确:“免版税,全球范围内复制、分析、测试、执行和/或公开展示、准备衍生作品、分发……[等等,等等]”即使是简单的短语在页面顶部,“GPL 兼容”应该会给您带来安慰。分享开源的东西。如果你愿意,甚至可以修改它。它是开源的是有原因的。
@alttag 在项目中复制或使用 GPLd 代码意味着同一项目中的所有其他代码现在也在 GPL 下。由于我不是版权律师,我不知道这对于网站上发布的代码意味着什么。
p
pymen

对于 python2,您可以在 csv_writer.writerows(rows) 之前使用此代码
此代码不会将整数转换为 utf-8 字符串

def encode_rows_to_utf8(rows):
    encoded_rows = []
    for row in rows:
        encoded_row = []
        for value in row:
            if isinstance(value, basestring):
                value = unicode(value).encode("utf-8")
            encoded_row.append(value)
        encoded_rows.append(encoded_row)
    return encoded_rows

j
jcomeau_ictx

我尝试使用 Bojan 的建议,但它把所有 None 单元格变成了单词 None 而不是空白,并将浮点数渲染为 1.231111111111111e+11,也许还有其他烦恼。另外,我希望我的程序同时在 Python3 和 Python2 下运行。所以,我最终把程序放在了顶部:

try:
    csv.writer(open(os.devnull, 'w')).writerow([u'\u03bc'])
    PREPROCESS = lambda array: array
except UnicodeEncodeError:
    logging.warning('csv module cannot handle unicode, patching...')
    PREPROCESS = lambda array: [
        item.encode('utf8')
        if hasattr(item, 'encode') else item
        for item in array
    ]

然后将所有 csvout.writerow(row) 语句更改为 csvout.writerow(PREPROCESS(row))

我本可以使用测试 if sys.version_info < (3,): 而不是 try 语句,但这违反了“鸭子打字”。我可能会重新访问它并使用 with 语句正确编写第一个单行代码,以摆脱悬空的打开文件和 writer,但随后我必须使用 ALL_CAPS 变量名,否则 pylint 会抱怨......无论如何都应该收集垃圾,并且无论如何只在脚本运行时持续。


v
vpathak

一个非常简单的技巧是使用 json 导入而不是 csv。例如,而不是 csv.writer 只需执行以下操作:

    fd = codecs.open(tempfilename, 'wb', 'utf-8')  
    for c in whatever :
        fd.write( json.dumps(c) [1:-1] )   # json dumps writes ["a",..]
        fd.write('\n')
    fd.close()

基本上,给定正确顺序的字段列表,json 格式的字符串与 csv 行相同,除了分别位于开头和结尾的 [ 和 ] 。 json 似乎对 python 2 中的 utf-8 很健壮。 *