什么是魔法函数
python中以__
开头,以__
结尾的函数就是魔法函数,类中的魔法函数是为了增强类的特性。魔法函数不能自定义。同时魔法函数定义之后不需要调用,解释器会自动进行调用。
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
def __getitem__(self,item): # 定义这个可以进行迭代
return self.employee[item]
company = Company(["tom","bob","jane"])
for em in company[:2]: # 可进行切片
print(em) # tom bob
python的数据模型以及数据模型对python的影响
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
def __len__(self): # 定义了getitem也可以实现len操作
return len(self.employee)
魔法函数一览
非数学运算
- 字符串表示:
__repr__
,__str__
- 集合、序列相关:
__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__ 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__
、__rxor__
、__ror__
- 增量赋值位运算符:
__ilshift__
、__irshift__
、__iand__
、__ixor__
、__ior__
举例1——abs
注意:自定制__abs__
也影响了abs()内置方法。
class Nums(object):
def __init__(self,num):
self.num = num
def __abs__(self):
return abs(self.num)
my_num = Nums(1)
abs(my_num) # 1
举例2——add
class MyVector(object):
def __init__(self,x,y):
self.x = x
self.y = y
def __add__(self,other_instance):
return MyVector(self.x+other_instace.x,self.y+other_instace.y)
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
说明:数学运算类似于C++的运算符重载。
举例说明魔法函数的重要性(len函数)
如果len()
方法调用的对象是Python内置的类型,如list,set,dict(cpython)等,会直接获取(有一个数据表示长度),而不需要去遍历,效率更高。
class Company(object):
def __init__(self,employee_list):
self.employee = employee_list
def __len__(self):
return len(self.employee)
company = Company(["tom","bob","jane"])
len(company) # 3
总结
- python解释器会尽量提到代码的性能
- python的魔法函数不会直接写死,比如没有len魔法函数,会通过调用getitem来计算得到并返回,提高了灵活性