魔法函数简介
魔法函数是 python 语言的一大特色,魔法函数能增强类的类型,并且可以扩展类的行为。比如新声明的一个类是不能被迭代的,但是我们可以通过增加 __getitem__
或 __iter__
这两个魔法函数使得类具备可迭代的行为。
这不同于 java,魔法函数不属于任何一个基类,是 python 中特有的特性,并且可以可是被附加到任何一个类上去。同时,魔法函数是 python 面向协议编程的基础,我们可以通过对类增加某些魔法函数使得类具备一些特定的行为。
魔法函数示例
在下面的例子中,本来 Company 类是不能做切片操作的,求其长度也没有意义,当然也不能进行迭代操作,但是 __getitem__
__iter__
__len__
三个魔法函数使得 Company 同时拥有了上面三种行为。
class Company:
def __init__(self, employee_list):
self.employee_list = employee_list
def __getitem__(self, item):
return self.employee_list[item]
def __iter__(self):
pass
def __len__(self):
return len(self.employee_list)
company = Company(['Tom', 'Bob', 'Jane'])
# __getitem__ 使得 Company 有了切片操作
company_s = company[:2]
# __getitem__ 使得 Company 可以进行迭代操作
# 注意,for 循环首先找的是 __iter__ 魔法函数,如果没有则找 __getitem__
for em in company:
print(em)
# __len__ 使得 Company 有了长度方法
print(len(Company))
在 len() 调用内置的类型 list,set,dict 的时候,其实使用的是底层的 c 语言,性能非常好。
上下文管理器
最常用的上下文管理器就是平时用的最多的 try…catch…finally 语句,python 中可以在类上定义上下文管理器,也可以通过装饰器在函数上定义上下文管理器。
下面定义类的上下文管理器,这里用到两个重要的魔法函数 __exit__
和 __enter__
,当进入上下文管理器的时候执行 enter 函数,而当上下文执行完毕的时候则执行 exit 函数。
# 上下文管理器
class Sample:
def __enter__(self):
print('Enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('Exit')
def perform_action(self):
print('Perform action')
with Sample() as sample:
sample.perform_action()
下面是在函数上定义上下文管理器
import contextlib
@contextlib.contextmanager
def file_open(file):
print('file open')
yield {}
print('file end')
with file_open('abc.txt') as f:
print('Perform action')
魔法函数一览
非数学运算:
字符串表示:
__repr__, __str__
__str__ 用于定制字符串格式化(类到字符串),__repr__类似,但是是开发模式下
集合序列相关:
__len__, __getitem__, __setitem__, __delitem__, __contains__
迭代相关:
__iter__, __next__
可调用:
__call__
with上下文管理器:
__enter__, __exit__
数值转换:
__abs__, __bool__, __int__, __float__, __hash__, __index__
元类相关:
__new__, __init__
属性相关:
__getattr__, __setattr__, __getattribute__, __setattribute__, __dir__
属性描述符:
__get__, __set__, __delete__
协程:
__await__, __aiter__, __anext__, __aenter__, __aexit__
数学运算:
一元运算符:
__neg__(-), __pos__(+), __abs__
二元运算符:
__lt__(<), __le__(<=) , __eq__(==), __ne__(!=), __gt__(>), __ge__(>=)
算术运算符:
__add__(+), __sub__(-), __mul__(*), __truediv__(/), __floordiv__(//),
__mod__(%), __divmod__, __pow__(**), __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__, __rxor__, __ror__
增量赋值位运算符:
__ilshift__, __irshift__, __iand__, __ixor__, __ior__