魔法函数的概念
python中以“__”(双下划线)开头和结尾的函数,如“__getitem__()”可以使类成为可迭代的类型,可以直接使用for循环对类对象(含有可迭代属性)进行遍历。一般不要自己命名魔法函数(一般也无效),尽量使用python自带的魔法函数。魔法函数并不是和类挂钩,也不归属于Object类,只是设计用来增强类的类型,是一种独立的存在,在任何对象中都可以定义。
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 employee in company:
print(employee)
company1 = company[:2]
for employee in company1:
print(employee)
1
2
3
4
5
6
7
8
9
10
11
classCompany(object):
def__init__(self,employee_list):
self.employee=employee_list
def__getitem__(self,item):
returnself.employee[item]
company=Company(["tom","bob","jane"])
foremployeeincompany:
print(employee)
company1=company[:2]
foremployeeincompany1:
print(employee)
如上例,python中的迭代类型就是实现了对应迭代魔法函数的类,for语句其实就是拿到一个对象的迭代器(实现__iter__()魔法方法),在python中,做的优化是,如果拿不到迭代器,解释器会查找有没有实现__getitem__()方法。
python的数据模型和数据模型对python的影响
魔法函数其实就是python数据模型的概念,理解数据模型对理解python的设计理念很重要。魔法函数会影响python的语法。如上例,实现了__getitem__()魔法函数,使得对象称为迭代类型,可以实现for遍历,同时也使对象成为序列类型,可以进行切片操作。魔法函数也会影响python的内置函数,如对company1做len()计算,得到结果为2。原因在于内置函数len()会优先调用__len__()魔法函数,如果没有,则会查找__getitem__()函数。
魔法函数的划分
python的魔法函数可以从两个维度划分,即“非数学运算”和“数学运算”,前者包括字符串表示、集合序列相关、迭代相关、可调用、with上下文管理器、数值转换、元类相关、属性相关、属性描述符、协程;后者包括一元运算符、二元运算符、算术运算符、反向算术运算符、增量赋值算术运算符、位运算符、反向位运算符、增量赋值位运算符。
字符串表示:__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__;
__str__:对字符串进行格式化时调用的,__repr__:开发模式调用的,与python语言做了紧密关联,如下例,直接调用company会输出abc,其他魔法函数也类似,此处其实是company.__repr__()自动调用,魔法函数不需要显示调用,只需要定义即可。
class Company(Object):
def __repr__(self):
return "abc"
company = Company()
company
1
2
3
4
5
classCompany(Object):
def__repr__(self):
return"abc"
company=Company()
company
len函数的特性
python中的len()方法对内置类型(如list、dict、set)进行计算时,性能会很高,因为这时候会走捷径,原因在于这些内置类型都是使用C语言实现的,在使用cpython解释器时,会直接读取这些类型内在维护的“长度”数据,而不是遍历这个对象,所以在python中尽量使用python原生的类型。以此为例,说明python内部,python解释器会尽可能的去提高语言的性能,同时,解释器在内部做了很多优化,如for语句会从__iter__退化到__getitem__,很灵活,在__getitem__中也小心的处理了异常。
喜欢 (0)or分享 (0)