对Python中的不可变对象进行操作时,新对象是如何创建的?
When operating on immutable objects in Python, how is the new object created?
我知道不可变对象不能就地改变。创建一个新对象并将其重新分配给相同的变量名。这样,我们就可以维护与变量的关联。在内部,变量指向不同的对象。
>>> 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不需要一个可以改变的东西去改变才能产生新的东西吗?如果我想把一根钉子钉在一块木头上,但那块木头是不变的,我怎么能得到一块被锤过的木头呢?
不变性是语言层面的一个概念。该语言指定该实现不会为您提供工具来修改创建后的字符串对象。
实现本身可能有 内部 工具,用于在创建字符串时修改它,然后才能让您访问它。
例如,在 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;
}
If I want to hammer a nail into a piece of wood, but that wood is
unchangeable, how do I end up with a hammered piece of wood?
在这个类比中,这意味着给你一块木头,上面已经有钉子,但没有给你一把锤子。语言实现已经为您敲定了木头,但您不能对它是如何做到的做出任何假设。它可能用了锤子,也可能在钉子周围长了一棵树。
我知道不可变对象不能就地改变。创建一个新对象并将其重新分配给相同的变量名。这样,我们就可以维护与变量的关联。在内部,变量指向不同的对象。
>>> 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不需要一个可以改变的东西去改变才能产生新的东西吗?如果我想把一根钉子钉在一块木头上,但那块木头是不变的,我怎么能得到一块被锤过的木头呢?
不变性是语言层面的一个概念。该语言指定该实现不会为您提供工具来修改创建后的字符串对象。
实现本身可能有 内部 工具,用于在创建字符串时修改它,然后才能让您访问它。
例如,在 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;
}
If I want to hammer a nail into a piece of wood, but that wood is unchangeable, how do I end up with a hammered piece of wood?
在这个类比中,这意味着给你一块木头,上面已经有钉子,但没有给你一把锤子。语言实现已经为您敲定了木头,但您不能对它是如何做到的做出任何假设。它可能用了锤子,也可能在钉子周围长了一棵树。