Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 460 – 添加二进制插值和格式化

作者:
Antoine Pitrou <solipsis at pitrou.net>
状态:
已撤回
类型:
标准跟踪
创建日期:
2014年1月6日
Python 版本:
3.5

目录

摘要

本 PEP 提议为 bytes 和 bytearray 对象添加最小化的格式化操作。提议的添加包括:

  • bytes % ...bytearray % ... 用于百分比格式化,语法类似于 str 对象的百分比格式化(接受单个对象、元组或字典)。
  • bytes.format(...)bytearray.format(...) 用于一种格式化,其语法类似于 str.format()(接受位置参数和关键字参数)。
  • bytes.format_map(...)bytearray.format_map(...) 用于一个与 str.format_map(...) 相似的 API,具有与 bytes.format()bytearray.format() 相同的格式化语法和语义。

基本原理

在 Python 2 中,str % argsstr.format(args) 允许对字节字符串进行格式化和插值。此功能通常用于组装协议消息,因为协议已知使用固定编码。

Python 3 通常强制要求文本以 Unicode(即 str 对象,而不是 bytes)的形式存储和操作。但在某些情况下,直接操作 bytes 对象是有意义的。典型用法是二进制网络协议,您可能希望对几个 bytes 对象(其中一些是字面量,一些是计算得出的)进行插值和组装,以生成完整的协议消息。例如,HTTP 或 SIP 等协议具有 ASCII 名称的标头以及使用可变且/或有时定义不明确的编码的不透明“文本”值。此外,这些标头可以跟一个二进制主体……它可以被分块并用 ASCII 标头和尾部进行装饰!

虽然有相当有效的方法可以累积二进制数据(例如使用 bytearray 对象、bytes.join 方法,甚至 io.BytesIO),但没有一种方法能产生像 % 格式化或 {} 格式化模板和格式化操作那样可读且直观的代码。

二进制格式化特性

支持的特性

在此提案中,bytesbytearray 的百分比格式化支持以下特性:

  • 通过位置和名称查找格式化参数(即 %s 以及 %(name)s)。
  • %s 将尝试获取给定值的 Py_buffer,并回退调用 __bytes__。生成的二进制数据将插入到字符串中的指定位置。这有望与 bytes、bytearray 和 memoryview 对象(以及其他一些对象,如 pathlib 的 path 对象)一起使用。
  • %c 将接受一个介于 0 和 255 之间的整数,并插入具有给定值的字节。

bytesbytearray 的大括号格式化支持以下特性:

  • str.format() 支持的所有参数查找类型(显式位置查找、自动增量位置查找、关键字查找、属性查找等)。
  • 在未指定修饰符或布局时插入二进制数据(例如 {}{0}{name})。这具有与百分比格式化的 %s(见上文)相同的语义。
  • ‘c’ 修饰符将接受一个介于 0 和 255 之间的整数,并插入具有给定值的字节(与上面的 %c 相同)。

不支持的特性

str 对象的格式化中存在的所有其他特性(通过百分号运算符或 str.format() 方法)均不支持。这些特性意味着将运算符或方法的接收者视为文本,这与文本/字节分离相悖(例如,接受 %d 作为格式代码将意味着字节对象实际上是一个 ASCII 兼容的文本字符串)。

除了大多数特定类型的格式代码外,各种布局说明符(如填充或对齐)也包含在这些不支持的特性中。此外,str 对象不能作为格式化操作的参数,即使在使用例如 %s 格式代码时也是如此。

__format__ 不会被调用。

批评

  • 开发成本和维护成本。
  • 在 3.3 版本中,编码到 ASCII 或 latin-1 与 memcpy 一样快(但仍然会创建一个单独的对象)。
  • 开发人员将不得不设法绕过二进制格式的缺失,如果他们想支持 Python 3.4 及更早版本。
  • bytes.join() 在连接字节字符串方面一直比 format 快(XXX *是这样吗?*)。
  • 格式化函数可以实现在第三方模块中,而不是添加到内置类型中。

其他提案

一种新的数据类型

有人提议创建一个专门用于“网络编程”的新数据类型。本 PEP 的作者认为这适得其反。Python 3 已经有几个主要类型用于处理二进制数据:bytesbytearraymemoryviewio.BytesIO

再添加一种类型会使用户感到困惑,并且会使库之间的互操作性更加困难(由于必要的转换,也可能不理想)。

此外,需要的不仅仅是一种类型,而是两种:一种不可变类型(以允许哈希),以及一种可变类型(因为在处理网络消息时通常需要高效的累积)。

决议

本 PEP 被 接受PEP 461 所取代,该 PEP 结合模运算符为 bytes 对象引入了更广泛的格式化语言。

参考资料


来源:https://github.com/python/peps/blob/main/peps/pep-0460.rst

最后修改:2025-02-01 08:59:27 GMT