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

Python 增强提案

PEP 349 – 允许 str() 返回 unicode 字符串

作者:
Neil Schemenauer <nas at arctrix.com>
状态:
已拒绝
类型:
标准跟踪
创建日期:
2005年8月2日
Python 版本:
2.5
发布历史:
2005年8月6日
决议:
Python-Dev 消息

目录

摘要

本 PEP 提议修改内置函数 str(),使其能够返回 unicode 字符串。这一改变将使编写同时适用于两种字符串类型的代码变得更容易,并且还会使一些现有代码能够处理 unicode 字符串。C 函数 PyObject_Str() 将保持不变,取而代之的是添加函数 PyString_New()

基本原理

Python 已经有了一段时间的 Unicode 字符串类型,但其使用尚未普及。大量的 Python 代码假定字符串数据表示为 str 实例。Python 的长期计划是逐步淘汰 str 类型,并对所有字符串数据使用 unicode。显然,必须提供平稳的迁移路径。

我们需要升级为 str 实例编写的现有库,使其能够在全 unicode 字符串世界中运行。在所有必要的库都具备此能力之前,我们无法切换到全 unicode 世界。一次性升级所有库似乎不可行。一个更现实的策略是单独使库能够操作 unicode 字符串,同时保留其当前的全部 str 环境行为。

首先,我们需要能够编写接受 unicode 实例的代码,而无需尝试将其强制转换为 str 实例。我们将此类代码标记为 Unicode-safe。Unicode-safe 库可以在全 unicode 世界中使用。

其次,我们需要能够编写代码,当仅提供 str 实例时,不会创建 unicode 结果。我们将此类代码标记为 str-stable。str-stable 的库可以被尚未 Unicode-safe 的库和应用程序使用。

有时编写既 str-stable 又 Unicode-safe 的代码很简单。例如,以下函数可以直接工作

def appendx(s):
    return s + 'x'

这并不令人惊讶,因为 unicode 类型旨在简化任务。原则是当 str 和 unicode 实例相遇时,结果是一个 unicode 实例。一个显著的困难出现在代码需要对象的字符串表示时;这种操作传统上通过使用内置函数 str() 来完成。

使用当前的 str() 函数会使代码不 Unicode-safe。将 str() 调用替换为 unicode() 调用会使代码不 str-stable。更改 str() 使其能够返回 unicode 实例将解决此问题。作为额外的好处,一些当前不 Unicode-safe 的代码(因为它使用了 str())将变得 Unicode-safe。

规范

内置函数 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')

这是否真的是一个 bug 值得商榷,因为 decode_header() 实际上操作的是字节字符串,而不是字符字符串。传递 unicode 实例的代码本身可能被认为是错误的。

替代解决方案

可以添加一个新的内置函数来代替更改 str()。这样做几乎不会引入向后兼容性问题。然而,由于兼容性问题预计会很少,更改 str() 似乎比添加新内置函数更可取。

basestring 类型可以更改为具有建议的行为,而不是更改 str()。然而,对于抽象基类型来说,这将是令人困惑的行为。

参考资料


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

上次修改:2025-02-01 08:59:27 GMT