如何在Python 3中使用raw_unicode_escape编码打印字符串?

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

下面这段代码在 Python 3.x 中会出错,错误信息是 TypeError: must be str, not bytes。这是因为现在 encode() 方法返回的是 bytes 类型,而 print() 只接受 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'))

3 个回答

0

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

这个函数和 repr() 类似,它会返回一个字符串,这个字符串是对象的可打印表示。不过,它会把 repr() 返回的字符串中那些非ASCII字符用 \x\u\U 的方式进行转义。这样生成的字符串和 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 中用 unic(或者你想叫的其他名字)代替 repr,在 Python 3 中代替 ascii

...不过,如果你想更小心一点,也可以用 elif sys.version_info[0] == 2: 来替代 else:

1

我无法重现你遇到的问题,你可以查看这个回答的之前版本,里面有我尝试的记录(这也解释了我在评论中的链接)。

不过:

看起来你是在试图通过自己做很多工作来强制设置写入文件时的编码。但在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()

5

我会直接使用:

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

如果你想在Python 3和Python 2.6中使用完全相同的代码(否则你可以在2.6中用repr,在Python 3中用ascii,但那样就不算“完全相同”了;-)。

撰写回答