news 2026/8/25 6:54:05

Python 魔术方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 魔术方法

Python 魔术方法(Magic Method / 双下划线方法__xxx__

特征:前后双下划线__名字__,又叫特殊方法。
不要手动直接调用它,Python解释器会在特定语法、内置操作触发时自动调用。

举个直观例子:

obj+obj2# 自动调用 obj.__add__(obj2)print(obj)# 自动调用 obj.__str__()len(obj)# 自动调用 obj.__len__()withobj:# 自动调用 __enter__ / __exit__forxinobj:# 自动调用 __iter__ / __next__

对比 Swift:相当于 Swift 的customDebugDescription+运算符重载、Sequence协议;Python靠魔术方法,Swift靠协议扩展。


一、基础常用魔术方法

1. 实例生命周期

  1. __new__(cls, *args, **kwargs)
    创建对象实例(分配内存),类方法,先执行。几乎很少重写。
  2. __init__(self, ...)

初始化实例,大家最熟。obj = A()→ 先__new__得到空对象,再调用__init__给属性赋值。
❗注意:__init__不创建对象,只是初始化。

  1. __del__(self)
    对象被垃圾回收销毁时触发。不要用来做资源释放!不可预测什么时候执行,资源释放优先用上下文管理器__enter__/__exit__,不要靠__del__
classDemo:def__init__(self,name):self.name=nameprint(f"__init__ 初始化{self.name}")d=Demo("aaa")

2. 字符串打印

  • __str__(self)str(obj)/print(obj),面向人阅读的字符串。
  • __repr__(self)repr(obj),调试、控制台输出,面向开发者,理想状态可以eval复原对象。
classUser:def__init__(self,name):self.name=namedef__str__(self):returnf"用户:{self.name}"def__repr__(self):returnf"User(name='{self.name}')"u=User("张三")print(u)# __str__ → 用户:张三print(repr(u))# __repr__ → User(name='张三')

3. 长度、下标访问(容器类)

  • __len__(self)len(obj)触发,必须返回int
  • __getitem__(self, key)obj[key]获取
  • __setitem__(self, key, val)obj[key] = val赋值
  • __delitem__(self, key)del obj[key]删除
classMyList:def__init__(self):self.data=[10,20,30]def__len__(self):returnlen(self.data)def__getitem__(self,idx):returnself.data[idx]ml=MyList()print(len(ml))# 调用 __len__print(ml[1])# 调用 __getitem__

4. 上下文管理器(就是刚才 with)

  • __enter__(self):进入with块执行,返回值赋值给as 变量
  • __exit__(self, exc_type, exc_val, exc_tb):退出with块,无论是否异常一定执行。
classCtx:def__enter__(self):print("进入")returnselfdef__exit__(self,et,ev,tb):print("退出,不管有没有报错都跑")withCtx()asc:pass

async协程上下文管理器:__aenter____aexit__,配合async with

5. 迭代器相关 for in

  • __iter__(self)for x in obj,返回迭代器对象
  • __next__(self):迭代取下一个,无数据抛StopIteration
classCounter:def__iter__(self):self.n=0returnselfdef__next__(self):ifself.n>=3:raiseStopIteration v=self.n self.n+=1returnvforiinCounter():print(i)

6. 运算符重载

__add__(self,other)# +__sub__(self,other)# -__mul__(self,other)# *__eq__(self,other)# ==__lt__(self,other)# <

示例:

classPoint:def__init__(self,x,y):self.x=x self.y=ydef__add__(self,other):returnPoint(self.x+other.x,self.y+other.y)def__eq__(self,other):returnself.x==other.xandself.y==other.y p1=Point(1,2)p2=Point(3,4)p3=p1+p2# 触发 __add__print(p3.x,p3.y)print(p1==p2)#触发 __eq__

7. 可调用对象__call__

实例本身可以像函数一样加括号调用obj()

classCalc:def__call__(self,a,b):returna+b c=Calc()res=c(2,3)# 调用 __call__print(res)#5

二、容易混淆的点

  1. 不要手动调用魔术方法!
    ❌ 不要写obj.__str__();✅写str(obj)。解释器帮你调用。

  2. 魔术方法是定义类行为的协议
    只要你实现对应的双下划线方法,Python语法、内置函数就知道该怎么处理你的自定义对象。
    类比Swift:实现协议,就获得对应语法能力。

Swift: 遵守CustomStringConvertible→ 获得print能力
Python: 实现__str__魔术方法 → 获得print能力

  1. 不是所有双下划线都是魔术方法:
    实例变量self.__abc,这是名称改写(name mangling)私有变量,不是魔术方法!
classA:def__init__(self):self.__secret=100# 私有属性,不是魔术方法!

魔术方法是类里面定义的函数def __xxx__(self):。实例属性前后双下划线不算。


三、高频速查表

魔术方法触发时机
__init__obj = Cls()实例初始化
__str__print(obj) / str(obj)
__repr__调试repr(obj)
__len__len(obj)
__getitem__obj[key]
__setitem__obj[key]=val
__enter__ / __exit__with obj:上下文管理器
__aenter__ / __aexit__async with obj:异步上下文
__iter__ / __next__for x in obj循环迭代
__call__obj()对象当做函数调用
__add__/__eq__+==运算符

四、举个完整小例子,上下文管理器类(复习刚才with)

classMyLock:def__enter__(self):print("加锁")returnselfdef__exit__(self,exc_type,exc_val,exc_tb):print("释放锁,异常也会执行")# 返回False异常向外抛出returnFalsewithMyLock():print("临界区执行")

threading.Lock之所以支持with,就是它内部已经实现了__enter____exit__魔术方法。

五、和Swift简单对照理解

Python魔术方法Swift等价机制
__str__CustomStringConvertible
__iter__/__next__SequenceIteratorProtocol
__add__运算符重载static func +
with(__enter__/__exit__)没有语法;用defer手动实现释放逻辑
__call__callAsFunction
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 6:53:08

DeepSeek Harness:从零构建可追溯的AI编程工作流

最近在探索 AI 编程工具时&#xff0c;发现了一个非常有意思的新项目——DeepSeek Harness。它不像传统的代码生成工具那样&#xff0c;给你一个黑盒结果就结束了&#xff0c;而是将整个 AI 交互过程拆解成一个个可插拔、可追溯的“插件”。无论是代码生成、代码审查&#xff0…

作者头像 李华
网站建设 2026/8/25 6:50:33

[063][调度模块]事件驱动的日志记录与高效查询体系

[063][调度模块]事件驱动的日志记录与高效查询体系 本文章代码: gitee , gitcode , github 1. 事件驱动架构&#xff1a;解耦调度与日志 任务状态变更时&#xff0c;ScheduleTaskManager 发布 ChangeStatusEvent&#xff0c;JobLogEventConsumer 异步消费&#xff08;需配置…

作者头像 李华
网站建设 2026/8/25 6:48:58

2026年智能离子棒将带来哪些惊喜?解密这款科技新宠的魅力

在科技飞速发展的2026年&#xff0c;智能离子棒作为改善生产问题的新宠&#xff0c;正崭露头角。而上海净源机电科技有限公司&#xff08;IONEAS&#xff09;的836/JX和600JL系列离子棒&#xff0c;更是凭借着卓越的技术优势和出色的应用能力&#xff0c;为众多行业带来了新的惊…

作者头像 李华
网站建设 2026/8/25 6:48:15

智慧楼宇安防一体化架构:从烟囱式部署到事件驱动联动引擎的演进

一、传统安防系统的痛点 传统智慧楼宇安防建设长期存在"烟囱式"部署问题。视频监控、门禁管理、入侵报警、消防联动等子系统各自独立运行&#xff0c;数据互不相通&#xff0c;告警难以关联&#xff0c;运维人员需要在多个平台间来回切换&#xff0c;效率低下。核心矛…

作者头像 李华
网站建设 2026/8/25 6:44:15

构建AI个人档案:从模型依赖到可迁移的工作流方法论

你有没有过这样的体验&#xff1a;花了好几天时间&#xff0c;终于让一个AI模型按照你的习惯和偏好&#xff0c;输出了满意的结果。你精心调整了提示词&#xff0c;保存了对话历史&#xff0c;甚至整理了一套专属的工作流程。然后&#xff0c;模型更新了&#xff0c;或者你换用…

作者头像 李华
网站建设 2026/8/25 6:42:18

多Agent系统工程化实战:从架构设计到部署运维

1. 项目概述&#xff1a;从概念到实践&#xff0c;多Agent系统的工程化之路最近两年&#xff0c;AI领域最让人兴奋的突破之一&#xff0c;无疑是智能体&#xff08;Agent&#xff09;从单打独斗走向了“团队协作”。你肯定也注意到了&#xff0c;无论是技术社区的热议&#xff…

作者头像 李华