Python 3:如何获得字节字符串的字符串表示?

9
在 Python 3 中,如何将字节字符串插入正常字符串并获得与 Python 2 相同的行为(即:仅获取转义码而没有b前缀或双反斜杠)?
例如:
Python 2.7:
>>> x = u'\u041c\u0438\u0440'.encode('utf-8')
>>> str(x)
'\xd0\x9c\xd0\xb8\xd1\x80'
>>> 'x = %s' % x
'x = \xd0\x9c\xd0\xb8\xd1\x80'

Python 3.3:

>>> x = u'\u041c\u0438\u0440'.encode('utf-8')
>>> str(x)
"b'\\xd0\\x9c\\xd0\\xb8\\xd1\\x80'"
>>> 'x = %s' % x
"x = b'\\xd0\\x9c\\xd0\\xb8\\xd1\\x80'"

注意在Python 3中,输出结果包含了b前缀和双下划线。我想得到的结果应该与Python 2中的一致。

在您的Python 3示例中,您正在插值到Unicode字符串中,而不是像Python 2中那样插入字节字符串。 - Martijn Pieters
3个回答

6
在Python 2中,你有strunicode类型。其中str表示简单的字节串,而unicode则表示Unicode字符串。
但在Python 3中,这种情况发生了改变:现在str是Python 2中的unicode,而byte则是Python 2中的str
因此,在执行("x = %s" % '\u041c\u0438\u0440').encode("utf-8")时,你实际上可以省略u前缀,因为它是隐含的。在Python中,所有未经明确转换的内容都是unicode。
在Python 3中,这将产生你的最后一行结果:
 ("x = %s" % '\u041c\u0438\u0440').encode("utf-8")

现在我来解释一下如何在最终结果之后进行编码,这是你应该始终遵循的步骤:首先接收一个对象,将其解码为Unicode(无论您使用哪种方法),然后在生成输出时,将其编码为您选择的编码方式。不要尝试处理原始字节串,那只会让代码难看且已被弃用。

5
在您的Python 3示例中,您正在插入到一个Unicode字符串中,而不是像您在Python 2中所做的那样插入到字节字符串中。
在Python 3中,bytes不支持插值(即字符串格式化等)。
要么是连接,要么使用Unicode并仅在插入时进行编码:
b'x = ' + x

或者

'x = {}'.format(x.decode('utf8')).encode('utf8')

或者

x = '\u041c\u0438\u0440'  # the u prefix is ignored in Python 3.3
'x = {}'.format(x).encode('utf8')

是的,结果后进行编码似乎是更好的选择。谢谢! - Marc Abramowitz

0
在Python 2中,字节字符串和普通字符串是相同的,因此str()不会进行任何转换。在Python 3中,字符串始终是Unicode字符串,因此对字节字符串使用str()会进行转换。
您可以自己进行所需的转换:
x2 = ''.join(chr(c) for c in x)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接