python 3.x 魔法函数
魔法函数
-
什么是魔法函数???
- python中定义以双下划线开始且以双下划线结束的函数,通常称谓魔法函数
- 魔法函数可以让我们随意调用.类的魔法函数不是某个类独有的,而是任何类都可以调用,来增强类的特性.
- 魔法函数直接影响python语法的本身.
- 魔法函数实际上影响python中的内置函数的调用
1 """ 2 普通方法遍历员工名 3 """ 4 5 6 class Company(object): 7 def __init__(self, employee_list): 8 self.employee_list = employee_list 9 10 11 company = Company(["tom", "jayden", "python"]) 12 13 # 遍历所有的员工名 14 # 结果: 15 # tom 16 # jayden 17 # python 18 for employee in company.employee_list: 19 print(employee)
1 """ 2 使用魔法函数来完成员工名的遍历 3 4 __getitem__()魔法函数作用: 5 将一个类变成可迭代的对象. 6 7 当for...in...遍历一个对象的时候,python解释器会查找该对象下是否有魔法函数__getitem__(), 8 如果有python解释器调用__getitem__()魔法函数,并且for...in...会从头到尾去增加参数item的值(0,1,2...), 9 直到__getitem__()魔法函数抛出异常时,for...in...循环结束. 10 如果该对象下没有__getitem__()函数,会抛出异常,TypeError: xxx object is not iterable 11 """ 12 13 14 class Company(object): 15 def __init__(self, employee_list): 16 self.employee_list = employee_list 17 18 def __getitem__(self, item): 19 # 参数item是序列的索引 20 return self.employee_list[item] 21 22 23 company = Company(["tom", "jayden", "python"]) 24 25 # 结果: 26 # tom 27 # jayden 28 # python 29 for employee in company: # company是可迭代对象 30 print(employee)
1 """ 2 魔法函数直接影响python语法的本身. 3 魔法函数实际上影响python中的内置函数的调用 4 """ 5 6 7 class Company(object): 8 def __init__(self, employee_list): 9 self.employee_list = employee_list 10 11 def __getitem__(self, item): 12 # 参数item是序列的索引 13 return self.employee_list[item] 14 15 16 company = Company(["tom", "jayden", "python"]) 17 18 # 结果: 19 # tom 20 # jayden 21 # python 22 for employee in company: # 通过魔法函数__getitem__()将company变成可迭代对象(影响python语法的本身.) 23 print(employee) 24 25 # 如果将对象中的魔法函数__getitem__()去除,再运行此代码会报错 26 # TypeError: 'Company' object is not subscriptable 27 # 证明出: 魔法函数影响python语法的本身 28 company1 = company[:2] 29 30 # 结果: 31 # tom 32 # jayden 33 for company in company1: 34 print(company) 35 36 # 结果: 2 37 # 如果将对象中的魔法函数__getitem__()去除,再运行此代码会报错 38 # TypeError: object of type 'Company' has no len() 39 # 证明出: 魔法函数实际上影响python中的内置函数的调用 40 print(len(company1))
-
python的数据模型以及数据模型对象python的影响
- python数据模型:
- 实际上在python本身的一种叫法里面魔法函数这个名词用的比较少,
- 只是网络上现在很多人喜欢把双下划线的函数叫做魔法函数.
- 实际上魔法函数是python数据模型的一个概念而已.
- 理解python的数据模型对理解python的一个设计理念非常重要.
- python数据模型:
-
魔法函数一览
-
非数学运算:
- 字符串表示:
- __repr__ : 开发模式下调用(单独执行一个对象,如: company = Company() --> company
- __str__ : 对对象进行字符串格式化时调用.如: print(company) --> 隐含执行print(str(company))
- 集合序列相关:
- __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__(divmod())
- __rpow__(** 或 pow())
- 增量赋值算术运算符:
- __iadd__(+)
- __isub__(-)
- __imul__(*)
- __itruediv__(/)
- __ifloordiv__(//)
- __imod__(%)
- __ipow__(** 或 pow())
- 位运算符:
- __invert__(~)
- __lshift__(<<)
- __rshift__(>>)
- __and__(&)
- __or__(|)
- __xor__(^)
- 反向位运算符:
- __rlshift__(<<)
- __rrshift__(>>)
- __rand__(&)
- __ror__(|)
- __rxor__(^)
- 增量赋值位运算符:
- __ilshift__(<<)
- __irshift__(>>)
- __iand__(&)
- __ior__(|)
- __ixor__(^)
- 一元运算符:
-
-
随便举个例子说明魔法函数的重要性(len()函数)
- len()函数的特殊性:
- 当在调用len()方法的时候会隐含的调用对象的内置函数__len__().
- 但是实际上len()方法做得远远不止这些,为什么???
- 如果计算某一个列表长度的时候,每一次都去遍历列表来获取长度的话,效率会比较低.
- 然而当len()方法里面用的是python中的内置类型(list,dict,set),对len()方法进行操作时,
- len()方法在python中会走一个捷径,那是什么捷径呢???
- python中list,dict,set这种原身的数据结构实际上都是用c语言来实现的,所以说它们的性能非常高.
- 当对这些内置数据类型做len()计算时,len()会直接读取c语言里的一个数据.就是列表的长度.
- 所以说在使用len()方法的时候,len()方法实际上直接走捷径,直接读取长度数据,而不是去变量数据.
- 所以说使用python的时候,尽量使用python的原身数据类型,
- 原身的数据类型,第一性能很高,第二对类型做长度统计的时候,由于python内部做优化.
- 所以说性能远远比我们自己用纯python来实现的高.
- for...in...遍历自定义类的流程:
- python解释器在遇到for...in...语句时,内部会做很多的工作,
- 比如在一个类中添加两个魔法函数__iter__(),__getitem__()时,
- python解释器会先调用__iter__()获取一个迭代器,然后对该类的实例对象进行遍历.
- 如果没有__iter__()函数,会调用__getitem__()函数,然后小心翼翼的处理好异常.
- len()函数的特殊性:
********
posted on 2019-04-03 09:41 jaydenjune 阅读(71) 评论(0) 收藏 举报
浙公网安备 33010602011771号