Python 理解类中self的含义

self代表的是类的实例,而不是类

class Test(object):
    def prt(self):
        print(self)
        print(self.__class__)

t = Test()
t.prt()

执行结果:

<__main__.Test object at 0x10fe90fd0>
<class '__main__.Test'>

从上面的执行结果可以看出,self指向是类的实例对象,self.__class__指向的类

self是必写的?

在Python解释器内部,当我们调用t.prt()时,实际上解释器解释为Test.prt(t),也就是说把self替换成类的实例

class Test(object):
    def prt(self):
        print(self)
        print(self.__class__)

t = Test()
# t.prt()
Test.prt(t)

代码与上面代码运行结果一样。

实际上self是不可以省略的

class Test(object):
    def prt():
        # print(self)
        # print(self.__class__)
        print('aaa')

t = Test()
t.prt()

运行结果:

TypeError: prt() takes 0 positional arguments but 1 was given

prt()方法在定义时没有定义参数,但是我们运行时强行传了一个参数,等同于我们传了一个参数t。

如果我们定义和调用时均不传类实例是可以的,这就是类方法:

class Test(object):
    def prt():
        # print(self)
        # print(self.__class__)
        print('aaa')

t = Test()
# t.prt()
Test.prt()

运行结果为:aaa

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

class Parent:
    def p(self):
        print(self)


class Child(Parent):
    def c(self):
        print(self)

cl = Child()
cl.c()
cl.p()
pa = Parent()
pa.p()

运行结果:

<__main__.Child object at 0x107cf4e90>
<__main__.Child object at 0x107cf4e90>
<__main__.Parent object at 0x107cf4e10>

运行cl.p()时,相当于Child.p(cl),所以self指的是Child类的实例,由于Child中没有定义p(),所以会沿着继承树往上找,在Parent类中有p()方法,所以就会成功调用

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

class Desc:
    def __get__(self, ins, cls):
        print('self in Desc: %s ' % self )
        print(self, ins, cls)
class Test:
    x = Desc()
    def prt(self):
        print('self in Test: %s' % self)
t = Test()
t.prt()
t.x

运行结果:

self in Test: <__main__.Test object at 0x105c26dd0>
self in Desc: <__main__.Desc object at 0x105c26d10> 
<__main__.Desc object at 0x105c26d10> <__main__.Test object at 0x105c26dd0> <class '__main__.Test'>

此处调用的是t.x,也就是说是Test类的实例t的属性x,由于实例t中并没有定义属性x,所以找到了类属性x,而该属性是描述符属性,为Desc类的实例而已,所以此处并没有顶用Test的任何方法。
那么我们如果直接通过类来调用属性x也可以得到相同的结果。

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

self in Test: <__main__.Test object at 0x10334cdd0>
self in Desc: <__main__.Desc object at 0x10334cd10> 
<__main__.Desc object at 0x10334cd10> None <class '__main__.Test'>

 

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值