【问题标题】:How can you print a string using raw_unicode_escape encoding in python 3?如何在 python 3 中使用 raw_unicode_escape 编码打印字符串?
【发布时间】:2011-03-03 14:09:20
【问题描述】:

以下代码在 Python 3.x 中使用 TypeError: must be str, not bytes 失败,因为现在 encode() 返回 bytesprint() 只需要 str

#!/usr/bin/python
from __future__ import print_function
str2 = "some unicode text"
print(str2.encode('raw_unicode_escape'))

如何使用print() 打印Unicode 字符串转义表示?我正在寻找适用于 Python 2.6 或更高版本(包括 3.x)的解决方案

更新

下面的行将适用于 3.x,但不适用于 2.6,生成 AttributeError: 'file' object has no attribute 'buffer'

sys.stdout.buffer.write(str2.encode('raw_unicode_escape'))

【问题讨论】:

    标签: python unicode python-3.x


    【解决方案1】:

    我无法重现您的问题,请参阅 previous revisions of this answer 获取我的尝试日志(其中解释了我在 cmets 中的链接)。

    但是:

    您似乎正试图在写入文件时通过自己完成所有的跑腿工作来强制编码。但是在 Python 3 中,open() 接受一个 encoding 参数,它可以为您完成所有的魔法。

    badp@delta:~$ python3
    Python 3.1.2 (r312:79147, Apr 15 2010, 12:35:07) 
    [GCC 4.4.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> foo = open("look mah, utf-32", "w", encoding="utf-32")
    >>> foo.write("bar")
    3
    >>> foo.close()
    >>> foo = open("look mah, utf-32", "rb")
    >>> foo.read()
    b'\xff\xfe\x00\x00b\x00\x00\x00a\x00\x00\x00r\x00\x00\x00'
    

    如果您正在寻找 Python 2 的等效版本,您似乎真的想使用 io.open()

    【讨论】:

    • 尝试从文件内部运行此操作,它不会起作用。从控制台接缝运行但不是从文件运行。我还添加了关于缓冲区使用的新评论。
    【解决方案2】:

    http://docs.python.org/py3k/library/functions.html#ascii

    作为 repr(),返回一个包含对象的可打印表示的字符串,但使用 \x、\u 或 \U 转义符对 repr() 返回的字符串中的非 ASCII 字符进行转义。这会生成一个类似于 Python 2 中 repr() 返回的字符串。

    结果字符串的类型确实是str,而不是bytes

    例子:

    >>> a = '''Ⴊ ⇠ ਐ ῼ இ ╁ ଠ ୭ ⅙ ㈣'''
    >>> ascii(a)
    "'\\u10aa \\u21e0 \\u0a10 \\u1ffc \\u0b87 \\u2541 \\u0b20 \\u0b6d \\u2159 \\u3223'"
    >>> print(ascii(a))
    '\u10aa \u21e0 \u0a10 \u1ffc \u0b87 \u2541 \u0b20 \u0b6d \u2159 \u3223'
    

    如果你想去掉多余的引号,你可以做print(ascii(a)[1:-1])

    编辑:正如 Alex 所说,您必须在 Python 2.6 中使用 repr 而不是 ascii。他的解决方案确实适用于 Python 2 和 3,但是如果您计划进行大量转换(因此更喜欢更容易多次键入的内容),一种可能性是在程序的开头放置一个条件,如下所示:

    import sys
    if sys.version_info[0] == 3:
        unic = ascii
    else:
        unic = repr
    

    然后,您只需在 Python 2 中使用 repr 和 Python 3 中使用 ascii 的任何地方使用 unic(或任何您想调用的名称)。

    ...虽然我想如果你想更小心一点,你可以使用elif sys.version_info[0] == 2: 而不是else:

    【讨论】:

    • ascii 不在 2.6 中。
    • @Alex:是的,但正如我回答中的引用所示,repr 是。
    • repr 在 Python 3 中不会用转义符替换非 ascii 字符——根据语言级别使用两个不同的函数(Python 2 中的 repr,P​​ython 3 中的 ascii)不是OP 要求,“适用于 Python 2.6 或更高版本(包括 3.x)的解决方案”。
    • @Alex:用一个简单的解决方案更新了我的答案。
    【解决方案3】:

    我只是使用:

    print(str2.encode('raw_unicode_escape').decode('ascii'))
    

    如果您希望 Python 3 和 Python 2.6 中的代码相同(否则您可以在 2.6 中使用 repr 在 Python 3 中使用 ascii,但这并不是真正的“相同”;-)。

    【讨论】:

    • 感谢 Alex,我目前正在寻找为 Python 2.6+/3.x 构建一组函数覆盖,以使其对 Unicode 更友好。我希望我会成功。关于如何覆盖 file.write 函数以使其接受字节的任何想法?它与stackoverflow.com/questions/984014/… 有关
    • @Sorin,如果您想同时接受 unicode 和字节字符串并区别对待它们,您通常会进行类型检查;有时你可以摆脱适应(例如,一个接受 unicode 字符串并原封不动返回它的方法,一个字节字符串并返回通过解码获得的 unicode 字符串)——但这有点远可以在评论中轻松讨论的内容,并且与原始问题非常不同,因此您可能想就此提出另一个单独的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-27
    • 1970-01-01
    • 2011-10-17
    • 2018-06-13
    相关资源
    最近更新 更多