python中的魔术方法(双下划线)
文章目录1. 构造与初始化 (最基础)2. 字符串表示 (打印与调试)3. 模拟容器行为 (让对象像列表/字典)4. 运算符重载 (让对象支持数学运算)5. callable 对象 (让对象像函数一样被调用)6. 上下文管理器 (用于 with 语句)7. 属性访问控制 (高级)先声明一点魔术方法以双下划线命名但是双下划线命名的不一定就是魔术方法还可能是内置属性如__main__。1. 构造与初始化 (最基础)方法作用调用时机__new__(cls, ...)真正创建实例的方法。返回新对象。在__init__之前调用用于控制实例创建如单例模式。__init__(self, ...)初始化实例。设置属性。对象创建后立即调用最常用。__del__(self)析构方法。对象被垃圾回收前调用通常不推荐依赖它做资源清理。代码classDemo:def__new__(cls):print(1. 创建对象)returnsuper().__new__(cls)def__init__(self):print(2. 初始化对象)2. 字符串表示 (打印与调试)方法作用调用时机__str__(self)给用户看的字符串。使用print(obj)或str(obj)时。__repr__(self)给开发者看的字符串调试用。在交互式命令行输入obj或repr(obj)时。__format__(self, spec)自定义格式化。使用f{obj:.2f}等格式字符串时。最佳实践repr应该尽量返回能重现对象的代码如 Person(‘Alice’, 20)而str应该是易读的文本如 Alice, 20岁。3. 模拟容器行为 (让对象像列表/字典)让你的类支持索引、长度计算和迭代。方法|作用|对应操作:---|:---|:---__len__(self)|返回长度。|len(obj) __getitem__(self,key)|获取元素。|obj[key] __setitem__(self,key,value)|设置元素。|obj[key]value __delitem__(self,key)|删除元素。|delobj[key] __contains__(self,item)|检查是否存在。|iteminobj __iter__(self)|返回迭代器。|forxinobj:(开始迭代)__next__(self)|返回下一个值。|迭代过程中自动调用代码classMyList:def__init__(self):self.data[1,2,3]def__len__(self):returnlen(self.data)def__getitem__(self,index):returnself.data[index]lMyList()print(len(l))# 调用 __len__ - 3print(l[0])# 调用 __getitem__ - 14. 运算符重载 (让对象支持数学运算)让你的对象可以使用 , -, *, 等符号。算术运算|方法|操作|方法|操作||:---|:---|:---|:---||__add__(self,other)|ab|__sub__(self,other)|a-b||__mul__(self,other)|a*b|__truediv__(self,other)|a/b||__floordiv__(self,other)|a//b|__mod__(self,other)|a%b||__pow__(self,other)|a b|||比较运算方法操作方法操作__eq__(self, other)a b__ne__(self, other)a ! b__lt__(self, other)a b__le__(self, other)a b__gt__(self, other)a b__ge__(self, other)a b代码classVector:def__init__(self,x,y):self.xx self.yydef__add__(self,other):returnVector(self.xother.x,self.yother.y)def__eq__(self,other):returnself.xother.xandself.yother.ydef__str__(self):returnfVector({self.x},{self.y})v1Vector(1,2)v2Vector(3,4)print(v1v2)# 调用 __add__ - Vector(4, 6)print(v1v2)# 调用 __eq__ - False5. callable 对象 (让对象像函数一样被调用)方法作用对应操作__call__(self, ...)让实例可以像函数一样执行。obj()代码classMultiplier:def__init__(self,factor):self.factorfactordef__call__(self,value):returnvalue*self.factor doubleMultiplier(2)print(double(5))# 输出 10就像调用函数 double(5)6. 上下文管理器 (用于 with 语句)让你的类支持 with open(…) as f: 这种语法自动管理资源如文件关闭、锁释放。方法作用__enter__(self)进入with块时执行返回值赋给as后面的变量。__exit__(self, exc_type, exc_val, exc_tb)离开with块时执行无论是否发生异常。代码classMyResource:def__enter__(self):print(资源打开)returnselfdef__exit__(self,exc_type,exc_val,exc_tb):print(资源关闭)# 返回 True 可以吞掉异常返回 False (或 None) 则抛出异常withMyResource()asres:print(正在使用资源)7. 属性访问控制 (高级)拦截对属性的读取、设置和删除操作。方法作用__getattr__(self, name)当访问不存在的属性时触发。__setattr__(self, name, value)每次设置任何属性时都触发小心死循环。__getattribute__(self, name)每次访问任何属性时都触发优先级最高慎用。__delattr__(self, name)删除属性时触发。总结什么时候用日常开发最常用的是init,str,repr,eq。数据结构开发常用len,getitem,iter。数学/科学计算库大量使用运算符重载 (add,mul等)。框架/库开发常用call,enter,exit,getattr。