Python Unicode 问题

2 投票
2 回答
780 浏览
提问于 2025-04-15 23:15

我从一个ZODB(Zope对象数据库)中获取了一些数据。我得到了一个mybrains对象。然后,我做了:

o = mybrains.getObject()

这样我就得到了一个“Person”对象在我的项目中。接着,我可以做

b = o.name

当我在我的类上执行print b时,我得到了:

José Carlos

还有print b.name.__class__

<type 'unicode'>

我有很多“Person”对象,它们被添加到一个列表中。

names = [o.nome, o1.nome, o2.nome]

然后,我尝试用这些数据创建一个文本文件。

delimiter = ';'
all = delimiter.join(names) + '\n'

没有问题。现在,当我执行print all时,我得到了:

José Carlos;Jonas;Natália
Juan;John

但是当我尝试把它写入文件时:

f = open("/tmp/test.txt", "w")
f.write(all)

我遇到了这样的错误(位置不完全一样,因为我更改了名字)

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 84: ordinal not in range(128)

如果我已经可以用“正确”的格式打印出来,为什么我不能用它来写文件呢?我应该使用什么编码/解码方法来写入这个数据的文件呢?

我正在使用Python 2.4.5(无法升级)

2 个回答

0

你让Python打印all,但因为all没有固定的计算机表示方式,所以Python首先需要把all转换成可以打印的形式。由于你没有告诉Python该怎么转换,它就默认用ASCII格式。可惜的是,ASCII只能处理0到127之间的值,而all包含了一些超出这个范围的值,因此你看到了错误信息。

要解决这个问题,可以使用:

all = "José Carlos;Jonas;Natália Juan;John"
import codecs
f = codecs.open("/tmp/test.txt", "w", "utf-8")
f.write(all.decode("utf-8"))
f.close()
3

Unicode编码错误: 'ascii' 编码器

write 方法在尝试用ascii编码字符串,但ascii编码无法处理带重音的字符,比如é或à。

你可以改用

import codecs
with codecs.open("/tmp/test.txt",'w',encoding='utf-8') as f:   
    f.write(all.decode('utf-8'))

或者选择其他编码方式(比如cp1252),这样就能正确编码你字符串中的字符。

另外,all.decode('utf-8') 是因为 f.write 需要的是unicode字符串。比起直接使用 all.decode('utf-8'),更好的做法是尽早把所有字符串转换成unicode格式,整个过程中都用unicode,最后再根据需要转换成特定的编码,比如'utf-8'。

另外,如果 names 已经是unicode字符串的列表,那就把 delimiter 也定义为unicode字符串:delimiter = u';',这样 all 就会是一个unicode字符串。然后

with codecs.open("/tmp/test.txt",'w',encoding='utf-8') as f:   
    f.write(all)

应该就能正常工作了(除非有我不知道的Python 2.4的问题)。

如果'utf-8'不行,记得尝试其他包含你需要字符的编码方式,确保你的电脑能识别。在Windows上,这可能意味着使用'cp1252'。

撰写回答