天天看点

python self

1. self代表类的实例,而非类

上面的例子,self 代表的是类的实例。而 self.class 则指向类。

2. self不必写成self

学过其他语言的,觉得 self 怪怪的,想写成 this,也是可以的。

改成 this,运行结果一样。但最好还是尊重约定俗成的习惯。

3. self可以不写吗

在 python 中,当我们调用 t.prt() 时,实际上 python 解释成 Test.prt(t),也就是说把 self 替换成类的实例。

运行时出错,因为 prt 没有参数,我们强行传了一个参数,t.prt() 等同于Test.prt(t)。

当然,我们可以定义和调用时均不传类的实例,这就是类方法。

4. 继承时,传入的是哪个实例,就是那个传入实例,而不是指定义了self的类的实例

运行 c.cprt() 时,指的是 Child 类的实例。

但是在运行 c.pprt()时,等同于 Child.pprt(c),所以 self 指的依然是 Child 类的实例,由于 self 中没有定义 pprt() 方法,所以沿着继承树往上找,发现父类 Parent 中定义了 pprt() 方法,所以就会调用。

5. 在描述符类中,self指的是描述符类的实例

为什么在 Desc 类中定义的 self 不是应该调用它的实例 t 吗?怎么变成了 Desc 类的实例了?

注意:这里调用的是 t.x,也就是说 Test 类的实例 t 的属性 x,由于实例 t 中没有定义属性 x,所以找到类属性 x,而该属性是描述符属性,为 Desc 类的实例而已,所以此处没有顶用 Test 的任何方法。

如果直接通过类来调用属性 x 也可以得到相同的结果。

下面是把 t.x 改为 Test.x 运行的结果。

题外话:由于很多时候描述符类中仍然需要知道调用该描述符的实例是谁,所以在描述符类中存在第二个参数 ins,用来表示调用它的类实例,所以 t.x 可以看到第三行中的运行结果中第二项 <_main_.Test object at 0x000002346022D308>。而采用 Test.x进行调用时,没有实例,返回None。

总结

self 在定义时需要定义,但是在调用时会自动传入

self 的名字并不是规定死的,但最好还是按照约定使用 self

self 总是指调用时的类的实例。