Python 的 setattr() 函数用于动态设置对象的属性值,是反射编程的核心工具。其语法和行为如下:
核心语法
setattr(object, attribute_name, value)
-
object:目标对象 -
attribute_name:属性名称(字符串) -
value:要设置的属性值
关键功能与示例
-
动态属性赋值
class User: pass user = User() setattr(user, 'name', 'Alice') 等价于 user.name = 'Alice' print(user.name) 输出: Alice -
批量初始化属性
class Config: pass config = Config() settings = {'timeout': 30, 'debug': True} for key, val in settings.items(): setattr(config, key, val) 动态设置多个属性 print(config.timeout) 30 -
覆盖现有属性
class Calculator: pi = 3.14 calc = Calculator() setattr(calc, 'pi', 3.1415926) 修改类属性值
与点号赋值的对比
| 场景 | 点号赋值 obj.attr = val
|
setattr(obj, 'attr', val) |
|---|---|---|
| 固定属性名 | ✅ 更简洁 | ⚠️ 需字符串包裹 |
| 动态属性名 | ❌ 无法实现 | ✅ 支持变量传递属性名 |
| 属性名含特殊字符 | ❌ obj.my-attr=1 语法错误 |
✅ setattr(obj, 'my-attr', 1)
|
| 批量设置 | ❌ 需逐行编写 | ✅ 支持循环批量操作 |
高级应用
动态扩展对象功能:
def greet(self):
return f"Hello, {self.name}!"
向类动态添加方法
setattr(User, 'greet', greet)
user = User()
user.name = "Bob"
print(user.greet()) Hello, Bob!
处理私有属性:
class SecureData:
def __init__(self):
self.__token = "secret" 名称修饰为 _SecureData__token
obj = SecureData()
setattr(obj, "_SecureData__token", "new_secret") 绕过名称修饰
注意事项
- 属性存在性:若属性不存在会新建属性(除非对象定义了
__slots__) - 触发魔术方法:调用时会触发对象的
__setattr__方法 - 安全风险:避免让用户直接控制
attribute_name参数,防止任意属性覆盖
💡 使用场景:配置文件加载、动态插件系统、ORM 框架属性映射等需要运行时操作属性的场景。