__setattr__用于控制属性赋值,每次设置属性时触发,可实现验证、只读等逻辑,需通过super().__setattr__或__dict__避免递归。

在 Python 中,__setattr__ 是一个特殊方法,用于控制对象属性的赋值行为。每当尝试设置对象的某个属性时,这个方法就会被调用。通过自定义 __setattr__,你可以实现属性验证、只读属性、动态属性管理等高级功能。
基本用法
__setattr__(self, name, value) 接收三个参数:
self:实例本身name:要设置的属性名(字符串)value:要设置的属性值
每次执行 self.attr = value 或 setattr(obj, ‘attr’, value) 都会触发它。
示例:
立即学习“Python免费学习笔记(深入)”;
class Person: def __init__(self, name): self.name = name # 这里也会触发 __setattr__def __setattr__(self, name, value): print(f"正在设置属性: {name} = {value}") super().__setattr__(name, value)
p = Person("Alice")p.age = 25
输出:
正在设置属性: name = Alice正在设置属性: age = 25
防止无限递归
在 __setattr__ 内部直接使用 self.name = value 会导致无限递归,因为它又会调用 __setattr__。
正确做法是使用父类的 __setattr__ 或操作实例的 __dict__:
super().__setattr__('name', value)self.__dict__['name'] = value
错误示例(会报 RecursionError):
def __setattr__(self, name, value): self.name = value # 错误!无限递归
实现属性验证或只读字段
你可以利用 __setattr__ 拦截非法赋值。
例如,限制某属性只能为特定类型:
class Temperature: def __init__(self, celsius): self._celsius = celsiusdef __setattr__(self, name, value): if name == "celsius": if not isinstance(value, (int, float)): raise TypeError("温度必须是数字") if value < -273.15: raise ValueError("温度不能低于绝对零度") super().__setattr__("_celsius", value) else: super().__setattr__(name, value)@propertydef celsius(self): return self._celsius
t = Temperature(25)t.celsius = 30 # 正常
t.celsius = "abc" # 抛出 TypeError
控制动态属性
有时你想禁止随意添加属性,只允许预定义的几个:
class StrictPerson: __slots__ = ['name', 'age'] # 更推荐用 __slots__# 或者用 __setattr__ 实现类似效果def __setattr__(self, name, value): if name not in {'name', 'age'}: raise AttributeError(f"不能设置属性 '{name}'") super().__setattr__(name, value)
基本上就这些。只要记住:每次赋值都会触发它,别在内部直接赋值导致循环,用 super() 或 __dict__ 安全操作。合理使用能增强类的行为控制。
以上就是python中使用_setattr_()的详细内容,更多请关注php中文网其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1382853.html
微信扫一扫
支付宝扫一扫