PEP 349 – 允许 str() 返回 unicode 字符串
- 作者:
- Neil Schemenauer <nas at arctrix.com>
- 状态:
- 已拒绝
- 类型:
- 标准追踪
- 创建时间:
- 2005-08-02
- Python 版本:
- 2.5
- 历史记录:
- 2005-08-06
- 决议:
- Python-Dev 邮件
摘要
本 PEP 提案修改 str()
内置函数,使其能够返回 unicode 字符串。 此更改将使编写能够处理两种字符串类型的代码变得更容易,并且还可以使一些现有代码处理 unicode 字符串。 C 函数 PyObject_Str()
将保持不变,而函数 PyString_New()
将被添加。
理由
Python 已经有一段时间拥有 Unicode 字符串类型,但其使用尚未普及。 存在大量 Python 代码假定字符串数据以 str 实例表示。 Python 的长期计划是逐步淘汰 str 类型,并对所有字符串数据使用 unicode。 显然,必须提供平滑的迁移路径。
我们需要升级为 str 实例编写的现有库,使其能够在全 unicode 字符串世界中运行。 在所有基本库都能够处理 unicode 字符串之前,我们无法转换到全 unicode 世界。 一次性升级所有库似乎不可行。 更加现实的策略是单独使库能够在 unicode 字符串上运行,同时保留其当前的全 str 环境行为。
首先,我们需要能够编写能够接受 unicode 实例而不会尝试将其强制转换为 str 实例的代码。 我们将此类代码标记为 Unicode 安全。 Unicode 安全的库可以在全 unicode 世界中使用。
其次,我们需要能够编写这样的代码:当只提供 str 实例时,不会创建 unicode 结果。 我们将此类代码标记为 str 稳定。 str 稳定的库可以被尚未 Unicode 安全的库和应用程序使用。
有时编写既 str 稳定又 Unicode 安全的代码很简单。 例如,以下函数可以正常工作
def appendx(s):
return s + 'x'
这并不奇怪,因为 unicode 类型旨在简化此任务。 原则是当 str 和 unicode 实例相遇时,结果是 unicode 实例。 当代码需要对象的字符串表示时,会出现一个值得注意的困难;传统上通过使用 str()
内置函数来完成的操作。
使用当前的 str()
函数会使代码不安全。 将 str()
调用替换为 unicode()
调用会使代码不稳定。 改变 str()
使其能够返回 unicode 实例将解决此问题。 作为进一步的益处,一些当前使用 str()
而非 Unicode 安全的代码将变得 Unicode 安全。
规范
以下是 str()
内置函数的 Python 实现
def str(s):
"""Return a nice string representation of the object. The
return value is a str or unicode instance.
"""
if type(s) is str or type(s) is unicode:
return s
r = s.__str__()
if not isinstance(r, (str, unicode)):
raise TypeError('__str__ returned non-string')
return r
以下函数将被添加到 C API 中,它等同于 str()
内置函数(理想情况下,它被称为 PyObject_Str
,但更改该函数可能会导致大量兼容性问题)
PyObject *PyString_New(PyObject *);
参考实现可以在 Sourceforge 上作为补丁获得 [1]。
向后兼容性
某些代码可能要求 str()
返回 str 实例。 在标准库中,到目前为止只发现了一种情况。 函数 email.header_decode()
需要 str 实例,并且 email.Header.decode_header()
函数尝试通过对其参数调用 str()
来确保这一点。 代码通过将“header = str(header)”行更改为以下内容来修复:
if isinstance(header, unicode):
header = header.encode('ascii')
这是否真的是一个错误值得怀疑,因为 decode_header()
实际上是在字节字符串上运行,而不是字符字符串。 向其传递 unicode 实例的代码本身也可能被认为是有问题的。
替代方案
可以添加一个新的内置函数,而不是更改 str()
。 这样做几乎不会引入向后兼容性问题。 但是,由于兼容性问题预计很少见,因此更改 str()
似乎比添加新的内置函数更可取。
可以更改 basestring 类型以具有提议的行为,而不是更改 str()
。 但是,对于抽象基类型来说,这将是令人困惑的行为。
参考资料
版权
本文件已进入公有领域。
来源: https://github.com/python/peps/blob/main/peps/pep-0349.rst
最后修改时间: 2023-09-09 17:39:29 GMT