You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时需要为Python类定义__getattr__()和__setattr__()方法?

Python中委托模式下__getattr__与__setattr__的使用指南

官方Python编程FAQ提到,在实现面向对象的**委托(delegation)**概念时,部分场景需要定义object.__getattr__(self, name)和object.__setattr__(self, name, value)方法,但未给出明确的通用判断标准。以下是结合示例和概念的具体说明:

FAQ示例解析

官方给出的示例用于实现一个类,它表现得像文件对象,但会把所有写入的内容转为大写:

class UpperOut:

    def __init__(self, outfile):
        self._outfile = outfile

    def write(self, s):
        self._outfile.write(s.upper())

    def __getattr__(self, name):
        return getattr(self._outfile, name)
  • 这里__getattr__的作用是:当访问UpperOut实例中不存在的属性/方法时,会自动委托给内部的_outfile对象处理。比如调用upper_out.close()时,因为UpperOut没有定义close方法,就会通过__getattr__调用_outfile.close()。
  • FAQ特别提示:如果需要支持设置或修改属性,定义__setattr__时要格外谨慎——如果直接在__setattr__里调用setattr(self, name, value)会触发无限递归,通常需要先处理自身属性,再委托给内部对象。

为什么不用继承?

有人疑惑这个示例为何不采用继承实现,原因在于这是为了演示无继承的纯委托模式:

  • Python 3中file并非独立类型,无法直接继承;
  • 更关键的是,普通继承会自动继承父类的所有属性和方法,不需要显式实现委托逻辑。而纯委托模式下,我们可以精确控制哪些行为自己处理,哪些委托给内部对象(比如示例中只重写了write方法,其他方法全委托)。

委托与继承的核心区别

根据维基百科的定义:

在面向对象编程中,委托指在一个对象的上下文中计算另一个对象的成员,可显式或隐式实现;隐式委托是原型编程中行为复用的基础,对应类编程中的继承。

狭义上:

  • 继承是类与类之间的关系(一个类继承自另一个类),属于类编程的复用方式;
  • 委托是对象与对象之间的关系(一个对象将请求委托给另一个对象处理),是原型编程的核心复用技术。

需要注意的是,委托在Python中并不属于常用的编程模式。


内容的提问来源于stack exchange,提问作者Lover of Structure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:16:28