1.先摘录原书的一段话:
首先明确一点,特殊方法的存在是为了被Python解释器调用的,你自己并不需要调用它们。也就说没有my_objiect.__len__()这种写法,而应该使用len(my_object)。在执行len(my_objiect)的时候,如果my_object是一个自定义的对象,那么Python会自己去调用其中由你实现的__len__方法(由你重写的)。
然而如果是Python内置的类型,比如列表(list),字符串(str),字节序列(bytearray)等,那么CPython(CPython是python的官方解释器,是由C语言编写的)会抄个近路,__len__实际上会直接返回PyVarObje里的ob_size属性。PyVarObje是表达内存中长度可变的内置对象的C语言结构体。直接读取这个值比调用一个方法要快的多。
能多时候,特殊方法的调用是隐式的,比如for i in x:这个语句,背后其实用的是iter(x),儿这个函数的背后则是下。__iter__()方法。当然前提是这个发发在x中被实现了。通常你的代码无需直接使用特殊方法。
2.下面是对书中代码的实现:
读者应该特别注意的是这些特殊方法对应的哪些操作。
如果你想将你的Vetor的一个实例打印出来,将会使用__repr__()这个方法,
如果你想进行向量加和,将会调用__add__()的方法,
如果你想进行数乘,将会调用__mul__()的方法,
如果你想知道向量的模长,解释器将会调用__abs__()方法,在写__abs__()这个方法时,我们使用了math模块中的hypot函数,
只有实现了__abs__()方法,我们才能去调用abs()这一内置函数,并且在__bool__()里面实现了对向量bool值的定义
这样,按照数中的代码,我们就基本实现了对向量的模拟。
2.1._repr__()方法是object类提供的方法,而所有的Python类都是object类的子类,因此所有的Python对象都具有__repr__()方法。所以如果需要将任何对象与字符串进行连接时,都可先调用方法将对象转为字符串,再将字符串连接在一起。
之所以特殊,是因为它是一个“自我描述”的方法,该方法通常实现场景是:当开发人员直接打印该对象时,系统将会输出该对象的“自我描述”信息,用来告诉外界该对象具有的状态信息。
2.3.object类提供的__repr__()方法总是返回该对象实现类的类名+object at + 内存地址值,这个返回值并不能真正实现“自我描述”的功能,因此如果用户需要自定义类能实现“自我描述”的功能,就必须重写__repr__()方法。
#这时摘自csdn上以为博主的
书中的特殊方法一览表在这里省略。
3.为什么len不是普通方法
len之所以不是一个普通方法,是为了让Python自带(内置)的数据结构可以走后门(所谓走后门,也就是说,CPython将会直接从一个C结构体中去读取对象的长度,完全不会调用任何方法,因此这就使得运行速度加快),abs也是同理。但是多亏了它时特殊方法,我们也可以把len用于自定义的数据类型。