【问题标题】:Python unicode problemPython unicode 问题
【发布时间】:2010-05-27 20:47:58
【问题描述】:

我正在从 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(无法升级)

【问题讨论】:

    标签: python unicode file-io


    【解决方案1】:

    UnicodeEncodeError: 'ascii' 编解码器

    write 正在尝试使用 ascii 编解码器对字符串进行编码(它无法对 é 或 à 等重音字符进行编码。

    改为使用

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

    或选择其他可以对字符串中的字符进行编码的编解码器(如 cp1252)。

    PS。上面使用了all.decode('utf-8'),因为f.write 需要一个unicode 字符串。 Better than using all.decode('utf-8') 将尽早将所有字符串转换为 unicode,在 unicode 中工作,并在后期编码为特定编码,如 'utf-8' -- 仅当你必须这样做时。

    PPS。看起来 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”。

    【讨论】:

    • Python 2.4 中是否可以使用 with 语句?
    • @Somebody:不幸的是,没有。它是在 Python 2.5 中实现的。如果您使用的是 Python 2.4,则别无选择,只能使用 f = open("/tmp/test.txt", "w")
    • 如果我从一个我无法控制的方法接收到它,我如何尽早将我的所有字符串转换为 unicode?我已经在变量中收到了“José Carlos”,而不是字符串文字。当我尝试执行 unicode(all, "utf-8") 我得到“TypeError:不支持解码 Unicode”...
    • 我只是想描述我的设置,感谢您的“在建议之前转换所有字符串”...
    • @unutbu:我不知道我之前是否做错了什么,但是添加 u' 做分隔符和 \n's,并从所有中删除 .decode,它起作用了。我在“导出”后打开了我的文件,它工作正常。谢谢你的帮助。我仍然不是这个主题的专家,但你对这个问题的解释可以作为一个开始。我也从这个资源red-mercury.com/blog/eclectic-tech/… 中学到了很多东西。
    【解决方案2】:

    您告诉 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()
    

    【讨论】:

    • 这不起作用... UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
    • 我添加了对 decode 的调用,然后以交互模式将我的代码剪切并粘贴到 Python 2.5 中,并在我的 Mac (Mac OS X 10.5.8) 上运行。它工作得很好。你还有问题吗?即使你先调用decode?​​span>
    • OP 以 Unicode 字符串开头,所以上面的 'all' 应该是 'all=u"..."'。然后只需 'f.write(all)' 和编解码器将 encode Unicode 字符串到文件。
    • -1 有两个原因 (1) 阅读 Mark 的评论 (2) 你的 all 是一个 str 对象,编码为 who-knows-what 编码;你的'utf8',西欧语言Windows系统中的cp850,......复制/粘贴到我的盒子上的(命令提示符)交互式解释器中,在utf8解码中死亡; OP 在 *x 平台上是一个意外,因此标准编码可能是 utf8。
    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 2013-09-10
    • 2013-03-21
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    相关资源
    最近更新 更多