Python 魔术方法 - zhongjiajie/zhongjiajie.github.com GitHub Wiki
首先明确一点,特殊方法的存在是为了被 Python 解释器调用的,你自己并不需要调用它们。也就是说没有 my_object.__len__()
这种写法,而应该使用len(my_object)
在执行len(my_object)
的时
候,如果 my_object 是一个自定义类的对象,那么 Python 会自己去调用其中由你实现的 __len__
方法。
通过内置的函数(例如 len
、iter
、str
,等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快
假设定义了一个类Magic
,那么定义了魔术方法后会有如下的效果
魔术方法在data model中有较为详细和完整的介绍
-
__repr__
: 定义返回对象的格式,调用这个对象时返回的格式(一般面向的时程序员),在REPL中输入这个对象时输出属于__repr__
,被repr
或者print
函数调用 -
__str__
: 定时输出的格式,类似print(object)
的输出格式(一般面向的时用户),如果__str__
没有定义但是__repr__
有定义时print会输出__repr__
的值,被str
函数调用-
__repr__
与__str__
的区别Difference between str and repr -
__repr__
注重准确性 -
__str__
注重可读性 - 容器的
__str__
包括了__repr__
- 如果
__repr__
定义了但是__str__
没有定义,就会__str__=__repr__
- 如果
-
-
__format__
: -
__bytes__
:
-
__abs__
: 获取对象的绝对值,通过abs
函数调用 -
__bool__
: 返回对象的bool类型,通过bool
函数调用,可以用于if while and or not
的组合运算.默认情况下,我们自己定义的类的实例总被认为是真的(如果__bool__
和__len__
没有定义),如果只定义了__bool__
没有定义__len__
则调用bool(obj)
的时候会调用__len__
,为0则返回False,反之返回True -
__complex__
: -
__int__
: -
__float__
: -
__hash__
: -
__index__
:
-
__len__
: 获取序列的长度,被len
函数调用.如果对象是一个内置类型,len()
方法会非常快,背后的原因是 CPython 会直接从一个 C 结构体里读取对象的长度,完全不会调用任何方法.len不是一个普通方法,len 之所以不是一个普通方法,是为了让 Python 自带的数据结构可以走后门 -
__getitem__
: 使序列的[]
方法生效,可以对其进行索引,切片,变成可迭代对象用for
进行迭代,用in
方法判断元素是否在序列中(__contains__
方法应该更好些) -
__setitem__
: -
__delitem__
: -
__contains__
:
-
__iter__
: -
__reversed__
: -
__next__
:
-
__call__
:
-
__enter__
: -
__exit__
:
-
__new__
: -
__init__
: -
__del__
:
-
__getattr__
: -
__getattribute__
: -
__setattr__
: -
__delattr__
: -
__dir__
:
-
__get__
: -
__set__
: -
__delete__
:
-
__neg__
: - -
__pos__
: + -
__abs__
:abs()
-
__add__
: + 通过+
中缀运算符调用,返回新对象,原对象不变,add
-
__sub__
: -subtract
-
__mul__
: * 通过*
中缀运算符调用,返回新对象,原对象不变,multiply
-
__div__
: /divide
, 现在一般用__truediv__
代表 -
__truediv__
: /divide
-
__floordiv__
: // -
__mod__
: % 取余数 -
__divmod__
:divmod()
-
__pow__
:**
或pow()
-
__round__
:round()
-
__iadd__
: 自增的加,+=
,对于可变对象相当于在可变对象调用append
或者extend
,这个时候的对象是原来的对象, id(Object)的值是不变的如果没有实现这个功能,则会调用__add__
,但是此时的对象id已经变成了别的id了,不可变对象一般不会实现这个功能,不可变对象使用+=
的时候会调用__add__
功能,生成一个新对象 -
__imul__
: 与__iadd__
类似
-
__lt__
: < -
__le__
: <= -
__eq__
: == -
__ne__
: != -
__gt__
: > -
__ge__
: >=