【问题标题】:When operating on immutable objects in Python, how is the new object created?在 Python 中对不可变对象进行操作时,新对象是如何创建的?
【发布时间】:2020-04-12 20:20:21
【问题描述】:

我了解不可变对象不能原地更改。创建一个新对象并将其重新分配给相同的变量名称。这样,我们可以保持与变量的关联。在内部,变量指向不同的对象。

>>> string = 'object'
>>> old_id = id(string)
>>> old_id
4452633584
>>> string = 'new' + string
>>> new_id = id(string)
>>> new_id
4501338544
>>> old_id == new_id
False

在上面的示例中,Python 是否会创建一个 可变string 克隆以连接到 'new',然后在重新分配给 string 之前使这个新对象不可变?

我不明白不能就地更改的对象如何也可以被操作。

难道 Python 不需要改变一个可改变的东西来产生一个新的东西吗?如果我想把钉子钉在一块木头上,但那块木头是不可改变的,我怎么会得到一块被锤过的木头呢?

【问题讨论】:

  • 看起来该字符串变量提供了值“对象”,并且与“新”连接,并且字符串变量根据您的代码重新分配了这个新值。所以它是 python 字符串加值而不是操作实际的字符串对象。

标签: python python-3.x immutability mutable


【解决方案1】:

不变性是语言级别的概念。该语言规定,一旦创建字符串对象,该实现不会为您提供修改字符串对象的工具。

实现本身可能有内部工具在创建字符串时对其进行修改,然后才可以访问它。

例如,在CPython string implementation 中,通过创建一个具有新大小的空PyUnicode 对象来执行字符串连接,该大小在内部表示字符串。然后在返回对象之前复制两个原始字符串中的字符:

PyObject *
PyUnicode_Concat(PyObject *left, PyObject *right)
{
    PyObject *result;
    /* […] */
    Py_ssize_t left_len, right_len, new_len;

    /* […] */

    left_len = PyUnicode_GET_LENGTH(left);
    right_len = PyUnicode_GET_LENGTH(right);

    /* […] */

    result = PyUnicode_New(new_len, maxchar);
    /* […] */
    _PyUnicode_FastCopyCharacters(result, 0, left, 0, left_len);
    _PyUnicode_FastCopyCharacters(result, left_len, right, 0, right_len);
    /* […] */
    return result;
}

如果我想把钉子钉在一块木头上,但那块木头是 不可改变,我怎么会得到一块敲过的木头?

在这个类比中,这意味着给你一块木头,里面已经有钉子,但没有给你一把锤子。语言实现已经为您确定了目标,但您不能假设它是如何做到的。它可能使用了锤子,也可能在钉子周围长了一棵树。

【讨论】:

    猜你喜欢
    • 2021-11-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 2020-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多