参考文章:
魔法函数讲解:https://zhuanlan.zhihu.com/p/344951719
具体魔法函数分析:https://blog.csdn.net/u012147447/article/details/83753450
描述符概念:https://www.zhihu.com/question/24455979
描述符
- 存储被描述物信息的数据结构
Python中的魔法函数
1 什么是魔法函数
- 为类增加一些额外功能的函数,以
__xx__()
的形式定义(不可以自定义)的函数,是Python 的一种高级语法
2 常见的魔法函数分类
- 非数学运算和数学运算两大类
2.1 非数学运算
2.1.1 字符串表示
__repr__
__str__
2.12 集合、序列相关
__len__
__getitem__
__setitem__
__delitem__
__contains__
2.13 迭代相关
__iter__
__next__
2.14 可调用
__call__
2.15 with上下文管理器
__enter__
__exit__
2.16 数值转换
__abs__
__bool__
__int__
__float__
__hash__
__index__
2.17 元类相关
__new__
__init__
2.18 属性相关
__getattr__
__setattr__
__getattribute__
__setattribute__
__dir__
2.19 属性描述符
__get__
__set__
__delete__
2.1.10 协程
__await__
__aiter__
__anext__
__aenter__
__aexit__
2.2 数学运算
2.21 一元运算符
__neg__
:-__pos__
:+__abs__
2.22 二元运算符
__lt__
:<__le__
:<=__eq__
:==__ne__
:!=__gt__
:>__ge__
:>=
2.23 算术运算符
__add__
:+__sub__
:-__mul__
:*__turediv__
:/__floordiv__
://__mod__
:%__divmod__
或divmod()
__pow__
或pow()
:**,指数__round__
或round()
2.24 反向算术运算符
__radd__
__rsub__
__rmul__
__rturediv__
__rfloordiv__
__rmod__
__rdivmod__
__rpow__
2.25 增量赋值算术运算符
__iadd__
__isub__
__imul__
__ifloordiv__
__ipow__
2.26 位运算符
__invert__
:~__lshift__
:<<__rshift__
:>>__and__
:&__or__
:|__xor__
:^,异或。a、b两个值不同,异或结果为1,反之为0
2.27 反向位运算符
__ilshift__
__irshift__
__iand__
__ixor__
__ior__
2.3 其他魔法函数
2.31 _unicode_()
__unicode__()
方法是在一个对象上调用unicode时被调用的
2.3.2 _delattr_()
删除属性,实现了该函数的类可以用python内置的del
命令来删除属性。
例如:MyClass中有work属性,直接del Myclass().work。
2.3.3 _del_()
__del__()
方法,功能正好和__init__()
相反,其用来销毁实例化对象。
在编写程序中,若之前创建的类实例化对象后续不再使用了,最好再适当的位置手动将其销毁,释放其占用的内存空间(整个过程成称为垃圾回收(简称GC:garbage collection))
Pyhon开发者不需要手动进行垃圾回收,因为Python有自动的垃圾回收机制,能自动将不需要使用的实例对象进行销毁
Python 采用自动引用计数(简称ARC:automatic reference counting)的方式实现垃圾回收机制。每个对象上都会配置一个计数器,初始时对象上的计数器值为0,当有变量引用改对象时,计数器+1,依次类推,反之则反。当对象上的计数器值为0时,则表明没有变量引用该Python对象,即证明程序不再需要它,此时Python就会自动调用__del__()
方法将其回收。
2.3.4 _dict_()
在Python类的内部,无论时类属性还是实例属性,都是以字典的形式进行存储的,其中属性名作为键,而值作为该键对应的值。
用类名.__dict__
则会显示类的属性,用实例对象.__dict__
则会显示实例对象中的属性
3 增加理解
3.1 getattr和getattribute的区别
https://blog.csdn.net/u012147447/article/details/83753450
当一个实例对象访问一个属性时,Python解释器搜索该属性的顺序为:
- 1 首先会在实例对象的
__dict__
属性里面找,看有没有这个属性,如TestClass().__dict__
- 2 若没有,则Python解释器会去该实例对象所属的类的
__dict__
属性里面去找,如TestClass.__dict__
- 3 如果还是没有的话,则Python解释器会去访问
__getattr__
这个方法,若没有定义该属性,则会产生AttributeError异常
第3步中会先调用__getattribute__
,如果还是找不到才会去调用__getattr__
。
相当于__getattr__
方法是专门用于处理那些原本在类或类实例中就未定义的属性,相对的__getattribute__
方法就是用于处理那些在类或类实例中已经有的属性。