概述
什么是魔法方法
魔法方法(魔法函数)是网上对 Python 数据模型的一个叫法。
在一个对象中,通过组合不同的魔法方法,会得到 Python 的各种数据类型。
Python 中以双下划线 '__' 开头和结尾的方法即魔法方法(Magic Methods)。
魔法方法会影响到 Python 本身的语法。
定义了魔法方法,不必去显示的调用它,Python 会在需要的时候(比如调用某些内置函数时,或应用了某些语法时)去调用它。
如何学习
从设计者的角度去理解
从 Python 内部设计理念的角度去理解
分类 1
构造方法
操作符
比较操作符
数值操作符
一元操作符
常见算数操作符
反射算数运算符
增强赋值运算符
类型转换操作符
类的表示
访问控制
自定义序列
反射
抽象基类
可调用的对象
上下文管理器
创建描述符对象
拷贝
Pickling
分类 2
数学运算
一元运算符
__neg__
-
__pos__
+
__abs__
abs()
二元运算符
__lt__
<
__le__
<=
__eq__
==
__ne__
!=
__gt__
>
__ge__
>=
算术运算符
__add__
+
__sub__
-
__mul__
*
__truediv__
/
__floordiv__
//
__mod__
%
__divmod__
divmod()
__pow__
** 或 pow()
__round__
round()
反向算术运算符
__radd__
__rsub__
__rmul__
__rtruediv__
__rfloordiv__
__rmod__
__rdivmod__
__rpow__
增量赋值算术运算符
__iadd__
+=
__isub__
-=
__imul__
*=
__itruediv_
/=
___ifloordiv__
//=
__imod_
%=
___ipow__
**=
位运算符
__invert__
~
__lshift__
<<
__rshift__
>>
__and__
&
__or__
|
__xor__
^
反向位运算符
__rlshift__
__rrshift__
__rand__
__ror__
__rxor__
增量赋值位运算符
__ilshift__
<<=
__irshift__
>>=
__iand__
&=
__ior__
|=
__ixor__
^=
非数学运算
类的表示
使用字符串来表示类是一个相当有用的特性。在 Python 中有一些内建方法可以返回类的表示,相对应的,也有一系列魔法方法可以用来自定义在使用这些内建函数时类的行为。
__repr__
__str__
__unicode__
__format__
集合、序列相关
__len__
__getitem__
__setitem__
__delitem__
__contains__
迭代相关
__iter__
__next__
可调用
__call__
with 上下文管理器
__enter__
__exit__
数值转换
__abs__
__bool__
__int__
__float__
__hash__
__index__
元类相关
__new__
__init__
属性相关
__getattr__
__setattr__
__getattribute__
__setattribute__
__dir__
属性描述符相关
__set__
__get__
__delete__
协程相关
__await__
__aiter__
__anext__
__aenter__
__aexit__
索引
__abs__
__add__
算术运算符 '+' 会隐含的调用 __add__ 方法。class MyVector:
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'
__aenter__
__aexit__
__aiter__
__and__
__anext__
__await__
__bool__
__bytes__
__call__
__ceil__
__class_getitem__
__cmp__
__coerce__
__complex__
__contains__
__copy__
__deepcopy__
__del__
__delattr__
__delete__
__delitem__
__delslice__
__dir__
__divmod__
__enter__
__eq__
__exit__
__float__
__floor__
__floordiv__
__format__
定义当类的实例用于新式字符串格式化时的行为,例如, “Hello, 0:abc!”.format(a) 会导致调用 a.__format__(“abc”) 。当定义你自己的数值类型或字符串类型时,你可能想提供某些特殊的格式化选项,这种情况下这个魔法方法会非常有用。
__fspath__
__ge__
__get__
__getattr__
__getattribute__
__getinitargs__
__getitem__
__getnewargs__
__getstate__
__gt__
__hash__
__hex__
__iadd__
__iand__
__idiv__
__ifloordic__
__ilshift__
__imatmul__
__imod__
__imul__
__index__
__init_subclass__
__instancecheck__
__int__
__invert__
__ior__
__ipow__
__irshift__
__isub____iter__
__itruediv__
__ixor__
__le__
__len__
当使用 len 方法去获取一个对象长度的时候,Python 会尝试调用 __len__ 方法来获取它的返回结果。
len 方法的实现是相对比较复杂的,当对 Python 内置类型相关的对象使用 len 方法时,性能是非常高的。因为在 CPython 中的 Python 内置类型大多是由 c 语言实现的。
__long__
__lshift__
__lt__
__matmul__
__missing__
__mod__
__mro_entries__
__mul__
__ne__
__neg__
__new__
__next__
__oct__
__or__
__pos__
__pow__
__prepare__
__radd__
__rand__
__rdiv__
__rdivmod__
__reduce__
__reduce_ex__
__repr__
str() 和 repr() 最主要的差别在于“目标用户”。 repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的 Python 代码),而 str() 则产生人类可读的输出。
定义对类的实例调用 repr() 时的行为。
__reversed__
__rfloordiv__
__rlshift__
__rmatmul__
__rmod__
__rmul__
__ror__
__round__
__rpow__
__rrshift__
__rshift__
__rsub__
__rtruediv__
__rxor__
__set__
__set_name__
__setattr__
__setitem__
__setslice__
__setstate__
__sizeof__
__str__
str() 和 repr() 最主要的差别在于“目标用户”。 repr() 的作用是产生机器可读的输出(大部分情况下,其输出可以作为有效的 Python 代码),而 str() 则产生人类可读的输出。
定义对类的实例调用 str() 时的行为。
print 函数在执行时,会默认调用 str 方法a = object()
print(a) == print(str(a)) # True
str 方法会尝试调用 mro 链上最近的 __str__ 或 __repr__ 方法,获取最终结果:# company.py
class Company:
def __init__(self, employee_list):
self.employee = employee_list
company = Company(['tom', 'bom', 'jane'])
print(company) #
# company.py
class Company:
def __init__(self, employee_list):
self.employee = employee_list
def __str__(self):
return ', '.join(self.employee)
company = Company(['tom', 'bom', 'jane'])
print(company) # 'tom, bom, jane'
# company.py
class Company:
def __str__(self):
return 'Company'
class MyCompany(Company):
def __init__(self, employee_list):
self.employee = employee_list
company = MyCompany(['tom', 'bom', 'jane'])
print(company) # 'Company'
__sub__
__subclasscheck__
__truediv__
__trunc__
__unicode__
定义对类的实例调用 unicode() 时的行为。 unicode() 和 str() 很像,只是它返回 unicode 字符串。注意,如果调用者试图调用 str() 而你的类只实现了 __unicode__() ,那么类将不能正常工作。所有你应该总是定义 __str__() ,以防有些人没有闲情雅致来使用 unicode。
__xor__