python中的双下方法---带你从底层逻辑看python(__str__、__repr__、__del__、__call__)

我们在写代码的过程中,往往都是直接去取调用函数,比如len(),print()input()等等,事实上,这些方法或者函数在调用过程中,触发了很多内在的运行机制和底层逻辑,深入研究之后,我们能看到不一样的python,下面跟大家分享几个双下方法及他们的运行逻辑。
双下方法:指的是带双下划线的方法,比如我们在类中非常常见的的__init__,今天我们要介绍的是__str__、reprdelcall
-----------------------------------分割线-----------------------------------
str
我们先定义这样一个类,并实例化:

class A:
    pass
a=A()
print(a)

输出结果是:
<main.A object at 0x0000026034D36E08>
这个结果其实是类的内存地址,同时可以看出他是object的一个子类,修改代码再次测试:

class A:
    pass
    def __str__(self):
        return '我已经打印了'
a=A()
print(str(a))
print(a)

这时输出结果为:
我已经打印了
我已经打印了
说明类中的__str__方法被调用两次,这其中的逻辑是:
当我们在类中调用str()方法,或者打印某个对象时,就会触发__str__方法,我们可以利用这一特性,设置需要的返回值作为参考;当对象a打印时,程序默认先调用对象a的__str__方法,当对象a没有设置时,则找到他的父类object去调用,这就是为什么我们设置了__str__方法时,会被触发的原因。
-----------------------------------分割线-----------------------------------
repr
repr() 函数将对象转化为供解释器读取的形式,简单说就是转化成其本来的形式。比如

a='1'
print(a)
print(repr(a))

打印结果:
1
‘1’
虽然a是字符串类型的数字,但当我们直接打印时,显示的是数字1,使用repr时,则会显示字符串的形式,也就是他的本来形式。还是上面同样的例子,我们将str改为repr

class A:
    def __repr__(self):
        return '我已经打印了repr'
a = A()
print(a)

结果如下:
我已经打印了repr

同样的,在类中打印对象时,会触发这个方法,看起来结果与__str__是一样的;如果__str__和__repr__同时存在时,顺序是如何的?代码测试下

class A:
     def __str__(self):
        return '我已经打印了str'
     def __repr__(self):
        return '我已经打印了repr'
a = A()
print(a)

结果如下:
我已经打印了str

运行逻辑:str__和__repr__同时存在时,优先执行__str,当没有__str__时,会继续执行__repr__。
-----------------------------------分割线-----------------------------------
del__析构方法:当我们的程序执行完成后,会释放内存,这时就会触发__del。比如下面的例子:

class A:
    def __del__(self):
        print( '我已经执行了')
a = A()
del a

我们在A类中实例化对象a,然后删除a,就会触发__del__方法。
结果如下:
我已经执行了
此时如果我们打印对象a,会发现结果如下:
NameError: name ‘a’ is not defined
说明我们使用del删除时,不仅仅会触发__del__方法,也会对对象删除,而且是先执行前者。
因为他不仅仅在使用del时触发,在程序结束,内存释放的时候也会被触发,我们可以使用__del__作为工作的收尾,所以比如关闭文件等操作。
-----------------------------------分割线-----------------------------------
call:这个方法平时我们很少见到,但却很有意思,先看下面的代码

class A:
    def __call__(self):
        print('我已经执行了')
a = A()()

执行结果:
我已经执行了

从上面的结果可以推测出,当对象加上()后,会触发__call__方法,实际运行结果也与我们推测的是一样的。
总结:
1)str:在类中打印时触发
2)repr:在类中打印时触发,但__str__存在时,优先执行__str__
3)del:在执行del或者内存释放时触发
4)call:在对象后加()时触发
更多应用,大家可以尝试摸索下

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学python的设计师

一年后再回首,为自己的成长惊喜

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值