python反射机制通过getattr和setattr实现运行时动态属性访问与修改,支持字符串命名、安全获取、动态赋值及插件扩展,但需注意性能与类型检查限制。

Python 的反射机制让程序能在运行时动态地访问和修改对象的属性与方法,getattr 和 setattr 是其中最常用、最基础的两个内置函数。它们不依赖硬编码的属性名,而是通过字符串来操作属性,极大提升了代码的灵活性和通用性。
getattr:安全获取对象属性
getattr(object, name[, default]) 用于从对象中获取指定名称的属性值。如果属性存在,返回其值;不存在时,若提供了 default 参数,则返回该默认值;否则抛出 AttributeError。
- 比直接用
obj.attr更健壮,避免因属性缺失导致程序中断 - 常用于配置驱动、插件系统或处理不确定结构的数据(如解析 JSON 后的对象)
- 支持获取方法,并可立即调用:
method = getattr(obj, 'do_something'); method()
setattr:动态设置对象属性
setattr(object, name, value) 用于给对象设置(或更新)指定名称的属性。它等价于 object.name = value,但名字是运行时决定的字符串。
- 适用于批量初始化、从字典填充对象、序列化反向还原等场景
- 注意:不能对不可变对象(如 int、str)或某些特殊类(未定义
__setattr__且为 slots 类)随意使用 - 配合 hasattr 或 getattr 可实现“有则更新,无则跳过”逻辑
典型组合用法与注意事项
反射不是“炫技”,而是在明确需要动态行为时的合理选择。常见模式包括:
立即学习“Python免费学习笔记(深入)”;
- 用字典批量赋值:
for k, v in data.items(): setattr(obj, k, v) - 安全调用可选方法:
if hasattr(obj, 'cleanup'): getattr(obj, 'cleanup')() - 避免硬编码字段名,提升配置兼容性(如 ORM 映射、API 响应解析)
- 慎用于性能敏感路径——反射比直接属性访问慢,且绕过了 IDE 和类型检查工具的提示
和 __getattribute__、__getattr__ 的区别
getattr 是用户级工具函数,而 __getattribute__ 和 __getattr__ 是类的特殊方法,控制属性访问的底层逻辑:
-
__getattribute__在每次属性访问时都被调用(包括存在和不存在),容易引发递归错误,需谨慎重写 -
__getattr__仅在属性查找不到时触发,适合实现“兜底逻辑”,比如动态生成属性或日志记录 -
getattr 内部会触发
__getattribute__,但不会触发__getattr__(除非显式调用)










