编程学习网 > 编程语言 > Python > 自从学会这几个魔法方法,我的Python类写得更优雅了!
2026
08-31

自从学会这几个魔法方法,我的Python类写得更优雅了!


上个月重构老项目,翻出一堆写了又删的代码。有个类光是初始化参数就十几个,每次实例化都像在填表格。

后来我花了一晚上研究魔法方法,改完自己都吓了一跳。同样的功能,代码量少了三分之一,同事看我的眼神都不太一样了。

先说 __new__  __init__ 的分工。以前我总把创建逻辑全塞进初始化里,后来才明白,__new__ 管的是造出个啥__init__ 管的是造出来之后怎么打扮。做单例模式的时候,重写 __new__ 比写装饰器直观多了,直接控制实例的诞生过程。

共享配置对象的时候,这段代码帮我省了好几次数据库连接。

class Config: 

   _instance = None

   def __new__(cls):

       if cls._instance is None:

           cls._instance = super().__new__(cls)

       return cls._instance

看着简单,但每次调用都拿到同一个对象,不用再担心全局变量被到处改。

__getattr__ 这个魔法方法救了我一次。有个老接口返回的字段名是动态的,有些对象有 user_name,有些只有 name。写一堆 if 判断太蠢了,我就用 __getattr__ 做了一层兜底。

def __getattr__(self, item): 

   if item == 'user_name' and hasattr(self, 'name'):

       return self.name

   raise AttributeError(f'{item} not found')

这样不管外部传什么字段名,我都能拿到正确的值。调用方不用知道内部字段命名差异,代码干净得像没处理过一样

再说 __setattr__。我以前写数据校验,每个 setter 方法都写一遍长度检查。后来直接在 __setattr__ 里拦一道,所有属性赋值都走同一个规则。

def __setattr__(self, key, value): 

   if key == 'phone' and len(value) != 11:

       raise ValueError('手机号必须11')

   super().__setattr__(key, value)

比在每个属性上写 property 快多了,改起来也省事,只动一个地方。

有个场景让我印象特别深。同事写了个日志类,每次打印都要拼时间戳和级别。后来我给他加了 __str__  __repr__ 的组合,让对象自己会说话。

def __str__(self): 

   return f'[{self.level}] {self.msg}'

def __repr__(self):

   return f'Log({self.level!r}, {self.msg!r})'

调试的时候直接 print(log_obj),看到的不是内存地址,是一眼能看懂的内容。信息直接印在对象上,比任何文档都清楚

__enter__  __exit__ 就不用多说了,写资源管理的类,文件、连接、锁,都靠它们收尾。以前我总忘了 close,现在 with 语句一结束,资源自动释放,不用惦记。

class FileReader: 

   def __enter__(self):

       self.file = open(self.path, 'r')

       return self.file

   def __exit__(self, args):

       self.file.close()

这段代码大概写了十几次了,每次都能帮我省掉排查资源泄漏的时间。

最后是 __call__。啥时候用呢,就是你想让一个对象看起来像个函数。之前写个回调处理器,一堆选项参数塞在构造函数里,调用时还得传个配置字典。改成 __call__ 之后,直接 handler(data) 就行,外部调用方根本不用知道内部怎么组织的。

def __call__(self, data): 

   return self.process(data)

这种写法让接口变薄了,依赖变少了,改动成本跟着降了。

还有个小技巧,用 __iter__ 让对象可以直接放进 for 循环。以前写个数据分页类,每次都要手动取下一批,现在直接 for item in pager,内部自动翻页。代码读起来像在说人话,不用猜内部机制

魔法方法不是炫技,是让你把重复逻辑收拢到一个地方。我见过太多人为了好看写一堆装饰器,结果层层包裹谁也看不懂。真正的优雅是让调用方感觉不到你的存在,数据给进去,结果拿出来,中间发生了什么,那不是调用方的事。

写类的时候,多想想哪些行为是 对象天生就该有的。比如比较大小用 __lt__,求长度用 __len__,这样你的类跟语言本身的特性就能咬合上,别人用起来也顺手。

别怕试,找个旧模块重构一下,把那些 if-else 挤掉的校验逻辑搬进魔法方法里。等你发现改动量变小了,测试用例不用跟着改,你就尝到甜头了。

以上就是“自从学会这几个魔法方法,我的Python类写得更优雅了!的详细内容,想要了解更多Python教程欢迎持续关注编程学习网。  

扫码二维码 获取免费视频学习资料

Python编程学习

查 看2022高级编程视频教程免费获取