Python这么灵活,他的魔术方法是什么?

胖琪的升级之路

共 1304字,需浏览 3分钟

 · 2020-10-12


点击上方「蓝字」关注我们

第一章 数据模型

魔术方法(dunder method 双下方法)

魔术方法的存在是为了被Python解释器调用的,自己不需要调用,「则在函数的外部就调用这类方法,例如从来不再外部写object.「dict」,object.「len」()这种写法」

怎么使用

既然已经有了这种魔术方法的出现,我们应该怎么使用的?比如我们有个实体类 Animal,想使用animal.「len」 这个函数。需要两步操作:

  1. 外部调用使用len()函数
  2. 在内部类重写__len__方法。

代码参考:

代码

上面定义了一个Animal类,我们在创建动物实例时,会将动物类型加载进去。并且重写了__len__这个魔术函数,让Animal这个类有了自己的长度。

那如果没有重新类的__len__是什么样的呢?

代码

所以为了保证能在外部用len函数,需要在类里面重写__len__该函数。

更多的魔术函数

在Python不止__len__一个魔术函数,还有很多魔术函数,例如__getitem__,「dict」.「add」,「mul」.

那竟然内部有这么多特殊方法,那么我们想要在外部使用怎么办?还是两步走。

  1. 重写对应的魔术方法
  2. 通过内置的函数或者隐式调用,比如 直接使用for i in x: ,背后就是调用的iter(x)方法。
  • 实现数据类的累加 数据类的累加其实原理是实现了该类的魔术方法__add__.

在实现该函数累加的时候,还重写了__repr__这个魔法函数,该功能是用来向人为展示类的可读性,如果没有重新该函数,则出现的是下图这种结果。结果对于人来说,不友好。

你看Python中的类结构想要使用的更加友好,我们完全在实现类时多使用魔术方法。

  • [ ] __repr__与__str__的区别:当一个对象没有重写__str__时,解释器会使用__repr__来代替。__str__会在函数str()中使用,或者是使用print()一个对象时调用。

除了 累加,我们还可以进行乘法,做布尔值.例子看

重写__mul__函数后,自定义类型也支持做乘法。

魔术方法一览表

当我们想在类中实现某个特殊方法时,在类中重新该函数即可。

不能让特例特殊到开始破坏既定规则

调用len函数时,使用的对象是一个内置对象,那么获取数据的结果的速度会非常快。这是Cpython从C结构体PyVarObject中获取结果,比通过一个方法要快很多。

同样通过魔术函数也让我们自定义的类型,也可以使用类似len()这样的内置函数。这种处理方式是保持内置类型的效率和保证语言的一致性找到了一个平衡。

你点的每个在看,我都认真当成了喜欢
浏览 70
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报