当使用现有 class 的属性创建新的 class 时,python 如何实例化属性?

How does python instantiate attributes when new class is created with attribute of existing class?

我有一个简单的 Point class,其属性为 zyz。我先实例化第一个对象:

point1 = Point(1, 2, 3)

现在我像这样实例化我的第二个点:

point2 = Point(point1.x, 3, 4)

当我运行id()点数和属性时我得到这个

id(point1): 1565146411848: x: 1, y: 2, z: 3 id(point1.x): 140711867415616
id(point2): 1565146435400: x: 1, y: 3, z: 4 id(point2.x): 140711867415616

显然这两个 Point 对象是唯一的,但是,它们似乎共享相同的 x

现在,当我更改时,说 point2.x = 900,会发生以下情况:

id(point1): 1565146411848: x: 1, y: 2, z: 3 id(point1.x): 140711867415616
id(point2): 1565146435400: x: 900, y: 3, z: 4 id(point2.x): 1565143647248

point2.x 现在不同于 point1.x。所以我假设在这些条件下的赋值点,创建了属性 x 的新实例?我不清楚这里 python 的规则是什么,我一直明白赋值不会导致实例化,但是看起来好像这正是这里发生的事情?这是如何工作的?

Python 变量——这包括对象的成员以及列表和字典元素之类的东西——是对值的 引用。当您创建 point2 并传入 point1.x 作为 x 值时,您将获得对相同值的新引用。这就是为什么它具有相同的 ID。

在这种情况下,这并不重要,因为整数是不可变的。如果你的 x 是一个像列表这样的可变对象,这可能很重要。尝试一下,看看当您通过任一对象的 x 引用更改列表时会发生什么(您会看到通过一个变量所做的更改会影响另一个变量)。

在整数的情况下理解这种行为还有另一个轻微的复杂性,即 CPython "interns" 小整数。也就是说,对整数 1 的每个引用最终都是对 1 的同一个副本的引用。尝试重复您的实验,但按字面意义传递 1 而不是 point1.x,您就会明白我的意思。