为什么 base64.b64encode() return 是字节对象?

Why does base64.b64encode() return a bytes object?

base64.b64encode() 的目的是将二进制数据转换为 ASCII 安全 "text"。但是,方法 returns 一个字节类型的对象:

>>> import base64
>>> base64.b64encode(b'abc')
b'YWJj'

简单地获取该输出并 decode() 它很容易,但我的问题是:base64.b64encode() 返回 bytes 而不是 str 的意义是什么?

b64encode() 不可能知道您想对其输出做什么。

虽然在许多情况下您可能希望将编码值视为文本,但在许多其他情况下(例如,通过网络发送)您可能希望将其视为字节。

因为b64encode()不知道,所以拒绝猜测。由于输入是 bytes,输出保持相同的类型,而不是被隐式强制为 str.

正如您所指出的,将输出解码为 str 很简单:

base64.b64encode(b'abc').decode('ascii')

...以及明确说明结果。

顺便说一句,值得注意的是虽然base64.b64decode()(注意:decode,而不是encode) 已接受 str 自版本 3.3 以来,更改为 somewhat controversial.

The purpose of the base64.b64encode() function is to convert binary data into ASCII-safe "text"

Python 不同意这一点——base64 被有意归类为 binary transform

Python3 中的设计决定强制字节和文本分离并禁止隐式转换。 Python 现在对此非常严格,以至于 bytes.encode 甚至不存在,因此 b'abc'.encode('base64') 会引发 AttributeError

该语言的观点是字节串对象已经编码。将字节编码为文本的编解码器不适合这种范式,因为当你想从字节域转到文本域时,它是一个解码。请注意,出于同样的原因,rot13 编码也从 standard encodings 列表中删除 - 它不适合 Python 3 范例。

还可以提出一个性能参数:假设 Python 自动处理 base64 输出的解码,它是 C 生成的 ASCII 编码二进制表示 binascii 模块中的代码,转换为文本域中的 Python 对象。如果你真的想要这些字节,你只需要通过再次编码成 ASCII 来撤销解码。这将是一个浪费的往返,一个不必要的双重否定。最好 'opt-in' 用于解码到文本的步骤。