0

我正在使用python 3.2,它处理转义字符的方式似乎几乎......不确定。我能让它们真正作为换行符(而不是作为转义符)工作的唯一方法是打印它们。行为如下所示:

>>> a = 'a\nb'
>>> a
'a\nb'
>>> a.encode('ascii')
b'a\nb'
>>> print(a)
a
b
>>> print(a.encode('ascii'))
b'a\nb'
>>> print(str(a.encode('ascii')))
b'a\nb'

我确信这其中的复杂性记录在某处,我只是找不到它。也许某处有一个字节->字符串方法与编码(解码?)相反。

4

1 回答 1

5

它是完全确定性和简单的。不过,您需要注意字节和 unicode 字符串之间的区别。阅读Ned Batchelder 的Pragmatic Unicode

a指由三个字符组成的 unicode 字符串,因此a对其进行评估,Python REPL 会尝试使用print()它——第一步是将其转换为 a str(仅return self用于字符串)。根据与标准输出(例如您的终端)关联的编码,将生成的字符串转换为字节,并将这些字节发送到那里。您的终端根据它使用的编码来解释它接收到的字节。

a.encode('ascii')使用 ASCII 编码将 unicode 显式转换为字节序列。其结果是一个字节对象,该结果print由 Python REPL 'd'。同样,第一步是将其转换为字符串——因为字节不是字符串,并且两者之间的隐式转换是非常有害的,正如 Python 2 编码/解码错误所证明的那样,你只会得到repr同样给你的东西:一个等价的字符串到 Python 源代码中的字节文字。然后像以前一样打印此字符串,相同的区别。

>>> print(a)中,您调用print自己的结果与上述相同,结果printNonePython REPL 不会打印它。与>>> print(a.encode('ascii'))and相同>>> print(str(a.encode('ascii'))),您只需显式触发打印并str预先进行转换,而不是隐式进行。

确实存在 的逆str.encode,它确实被称为decode并且是bytes对象的方法。所以some_str.encode(E).decode(E)可以是无操作的。它还可能丢失信息或沿途更改字符串(例如,通过替换未知字符),或者如果您不要求它丢失信息,则抛出异常。

如果您有以某种编码表示某些字符串的字节,则可以将它们用于 I/O。事实上,这是执行 I/O 的“本机”方式——所有 I/O 和所有网络都是字节。但print适用于字符串。相反,在文件 I/O(包括标准输出)的情况​​下,您希望以二进制模式打开它们并使用该.write方法。具体来说sys.stdout,默认情况下使用文本模式,但您可以访问二进制版本作为sys.stdout.buffer. 当然,如果您发送的字节是使用不同的编码创建的(或者根本不打算作为文本),您会得到胡言乱语。

于 2012-08-25T22:29:59.363 回答