Python进阶笔记(二)魔法函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29027865/article/details/87036848

2.1 什么是魔法函数

Python中的魔法函数就是以双下划线开头和结尾的函数,这些函数可以让我们自己随意的制定自定义类的特性。
魔法函数可以在任意一个自定义类中重写,因此它其实不是object类的一个方法。

如果没有魔法函数,我们想遍历一个类对象,需要这样:
在这里插入图片描述

有了魔法函数,再去调用for语句时,for语句实际上会去找Company类这个对象,它有没有__getitem__这个函数,如果有这个函数,一直遍历到抛异常为止。
在这里插入图片描述
事实上,我们通过魔法函数,就加强了我们自定义类Company,其本身是class的类型,当我们定义了__getitem__方法后,Company就又变成了一个可迭代的类型,可迭代类型就可以直接使用for语句来循环。
最后再来复习一下for em in company的过程:
for循环其实是拿到了一个迭代器,但是company对象是没有迭代器的,迭代器是需要实现__iter__方法,如果拿不到迭代器,python就会去找看是否有__getitem__这个方法,如果有的话,则调用这个方法,直至执行完。

2.2 Python的魔法函数

数据模型其实就是魔法函数的一个叫法,
python语法实际上是会识别我们的一个对象,或者说是自定义类里面的一个魔法函数,魔法函数的调用是隐式的,它属于独立的类块,目的是为了增加自定义类的性能。
Python的魔法函数包括很多类,这里不多展开,在这里以字符串表示的魔法函数__repr__和__str__作为例子:
同样我们自定义一个Company类,我们打印Company对象时,发现其输出的是对象的信息,那如果我们希望打印对象时,以一种我们自定义的字符串格式显示出来,该如何操作呢?
在这里插入图片描述
print方法会隐含的调用str方法,那我们可以定义魔法函数__str__来实现自己的print:
在这里插入图片描述
我们看到,因为print是隐含着调用了str方法,所以print会输出对象的实例子,而直接company,其实质是调用了repr方法,故其没有改变,当我们改变了repr,就可以正常打印:
在这里插入图片描述
魔法函数其实和python本身有关联,其和继承的对象没有关系。它并不是需要继承了某个对象,才会有某种方法,魔法函数是可以写在任意一个类中去。
比如调用repr魔法函数,实际上python会隐含的去调用repr(company),接着repr回去寻找__repr__实现调用,只是这个调用repr()的方法是隐含的。其等同于company.repr()。实际上,一些数学函数方法的调用,如:abs(),也是由调用魔法函数实现的。
下面我们通过算术运算符实现向量的加法:

class MyVector(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self,other_instance):
        # 实例化一个新的对象
        re_vector = MyVector(self.x+other_instance.x,self.y+other_instance.y)
        return re_vector
    def __str__(self):
        return "x:{x},y:{y}".format(x=self.x,y=self.y)
    
first_vec = MyVector(1,2)
second_vec = MyVector(2,3)
print(first_vec+second_vec)
---------
x:3,y:5

2.3 魔法函数len()

我们常常使用len()来直接拿到list,set.dict等数据类型的长度,那么在真实的过程中,len()是如何执行的呢?
与for先寻找迭代器再寻找__getitem__一样,调用len时,python也会先去找魔法函数的len实现,即:
在这里插入图片描述
但其实在len真实的调用中,远比这个情况复杂,当len处理dict,list,set这些内置类型时,其并不是直接就开始遍历然后个数累加,而是通过python的底层cpython中(内置类型是用c实现的),读取cpython中的一个保存的数据长度,来走捷径的获得这些内置类型的len,所以len在处理内置函数时的效率会非常高。

猜你喜欢

转载自blog.csdn.net/qq_29027865/article/details/87036848