2.魔法函数
1. 什么是魔法函数?
- Python里面的魔法函数,是以双下划线开头和结尾
- 魔法函数不依赖任何类,并且可以随时调用
- 一旦类里面加上一些特定的魔法函数,整个类就被附加了一些特定的功能.
- 魔法函数定义了我们不需要显式的调用它,Python解释器自己会知道什么情况下会调用,我们在使用相应的语法的时候就会自动调用。
- 魔法函数和本身的类没有关系,和类的父类,object也没有关系。魔法函数可以写到任意一个类中,跟继不继承没有必然的关系。
2. 实例
- for循环的是可迭代对象, 首先通过__iter__得到一个迭代器, 然后不断调用迭代器的__next__, 但是如果对象没有实现 __iter__或__next__迭代器协议,Python的解释器就会去寻找__getitem__来迭代对象,如果连__getitem__都没有定义,这解释器就会报对象不是可迭代对象的错误.
- 魔法函数是能影响到语法本身的, 本来company是无法进行切片操作, 但是由于实现了__getitem__, 所以在python的语法上我们可以对实例化的对象进行切片操作.(列表也是list这个类实例化得到的一个对象)
1 | class Company(object): |
3. 常用魔法函数(非数学运算类型)
3.1 字符串表示
- __repr__
- __str__
3.2 集合序列相关
- __len__
- __getitem__
- __setitem__
- __delitem__
- __contains__
3.3 迭代相关
- __iter__
- __next__
3.4 可调用
- __call__
3.5 with上下文管理器
- __enter__
- __exit__
3.6 数值转换
- __abs__
- __bool__
- __int__
- __float__
- __hash__
- __index__
3.7 元类相关
- __new__
- __init__
3.8 属性相关
- __getattr__
- __setattr__
- __getattribute__
- __setattribute__
- __dir__
3.9 属性描述符
- __get__
- __set__
- __delete__
3.10 协程
- __await__
- __aiter__
- __anext__
- __aenter__
- __aexit__
4. 常用魔法函数(数学运算类型)
4.1 一元运算符
- __neg__(-)
- __pos__(+)
- __abs__
4.2 二元运算符
- __lt__(<)
- __le__ <=
- __eq__ ==
- __ne__ !=
- __gt__ >
- __ge__ >=
4.3 算术运算符
- __add__ +
- __sub__ -
- __mul__ *
- __truediv__ /
- __floordiv__ //
- __mod__ %
- __divmod__ 或 divmod()
- __pow__ 或 ** 或 pow()
- __round__ 或 round()
4.4 反向算术运算符
- __radd__
- __rsub__
- __rmul__
- __rtruediv__
- __rfloordiv__
- __rmod__
- __rdivmod__
- __rpow__
4.5 增量赋值算术运算符
- __iadd__
- __isub__
- __imul__
- __itruediv__
- __ifloordiv__
- __imod__
- __ipow__
4.6 位运算符
- __invert__ ~
- __lshift__ <<
- __rshift__ >>
- __and__ &
- __or__ |
- __xor__ ^
4.7 反向位运算符
- __rlshift__
- __rrshift__
- __rand__
- __rxor__
- __ror__
4.8 增量赋值位运算符
- __ilshift__
- __irshift__
- __iand__
- __ixor__
- __ior__
5. 调试工具
notebook
首先使用pip install -i https://douban.com/simple notebook
安装然后运行ipython notebook
6. 字符串表示
- __str__
在打印一个实例化对象的时候, python默认会调用str(对象), 对应的魔法函数是__str__
1 | class Company(object): |
- __repr__
__repr__是在开发模式下调用的
1 | class Company(object): |
再次强调, __repr__不是因为该类继承了某一个对象才能去写这个方法, 魔法函数可以写到任何一个定义的类中去, 然后python解释器就是识别出这个对象有该特性, 然后再调试模式下company会被解释器转换为repr(company), 然后再去调用company.__repr__().
1 | class Company(object): |
7. len函数
之前提到len函数式会调用对象的__len__, 如果是使用遍历的方式求长度那么效率会很低, 但是在求python内置类型的长度比如len(list)、len(dict)、len(set)等的时候会很快, 因为在cpython中的list、dict、set等是通过c语言实现的, 在其内部会维护一个数据表示长度,所以就不需要进行遍历,能大大提高效率, 所以尽量使用python原生的数据类型
评论