为字符串分配另一个变量是否会复制或增加引用列

2024-05-20 03:42:52 发布

您现在位置:Python中文网/ 问答频道 /正文

在大卫比兹利的《Python基本参考》第35页,他首先声明:

For immutable data such as strings, the interpreter aggressively shares objects between different parts of the program.

然而,在同一页的后面,他说

For immutable objects such as numbers and strings, this assignment effectively creates a copy.

但这不是矛盾吗?一方面,他说它们是共享的,但随后他又说它们是复制的。


Tags: the声明fordataobjectsasbetween大卫
2条回答

python中的赋值永远不会创建副本(仅当类成员的赋值被重新定义(例如使用__setattr__、属性或描述符)时,技术上才有可能)。

所以之后

a = foo()
b = a

foo返回的内容没有被复制,而是有两个变量ab指向同一个对象。不管对象是否不变。

然而,对于不可变对象,很难判断是不是这样(因为不能使用一个变量对对象进行变异,并使用另一个变量检查更改是否可见),所以您可以自由地认为,ab确实不能相互影响。

对于一些不可变的对象,Python也可以自由地重用旧的对象,而不是创建新的对象

a = x + y
b = x + y

其中xy都是数字(所以总和是一个数字并且是不可变的)可能是ab都指向同一个对象。请注意,没有这样的保证。。。也可能是它们将指向具有相同值的不同对象。

要记住的重要一点是,除非特别指示使用copydeepcopy,否则Python永远不会进行复制。这对于可变对象非常重要,以避免意外。

一个常见的习惯用法是:

class Polygon:
    def __init__(self, pts):
        self.pts = pts[:]
    ...

在这种情况下,使用self.pts = pts[:]而不是self.pts = pts来复制整个点数组,以确保如果在创建对象之后将更改应用于传递给构造函数的列表,则不会意外更改点列表。

它有效地创建了一个拷贝。它实际上并没有创建副本。两个副本和两个名称共享相同值的主要区别在于,在后一种情况下,通过一个名称进行的修改会影响另一个名称的值。如果值不能被改变,这个差异就消失了,所以对于不可变对象来说,值是否被复制几乎没有实际意义。

在某些情况下,即使对于不可变类型(例如,使用id函数或is运算符),也可以区分副本和不同对象之间的区别,但对于Python内置的不可变类型(如字符串和数字)来说,这些都是不有用的。

相关问题 更多 >