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-01-06
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 对象是有意义的。典型用例是二进制网络协议,您可能希望插值和组装多个字节对象(其中一些是文字,一些是计算),以生成完整的协议消息。例如,HTTP 或 SIP 等协议具有 ASCII 名称的标头和使用不同且/或有时定义不明确的编码的非透明“文本”值。此外,这些标头后面可以是二进制主体……它可以被分块并用 ASCII 标头和尾部装饰!

虽然有一些合理有效的累积二进制数据的方法(例如使用 bytearray 对象,bytes.join 方法甚至 io.BytesIO),但它们都没有导致由 %-格式化或 {}-格式化模板和格式化操作生成的易读且直观的代码。

二进制格式化功能

支持的功能

在此提案中,用于 bytesbytearray 的百分比格式化支持以下功能

  • 按位置和名称查找格式化参数(即 %s 以及 %(name)s)。
  • %s 将尝试在给定值上获取 Py_buffer,并回退到调用 __bytes__。生成的二进制数据插入字符串中的给定位置。这预计适用于 bytes、bytearray 和 memoryview 对象(以及其他几个对象,例如 pathlib 的路径对象)。
  • %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 淘汰,该提案引入了与模运算符结合使用的更扩展的字节对象格式化语言。

参考资料


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

最后修改:2023-09-09 17:39:29 GMT