exception - 覆盖 __setattr__ 时的无限递归
问题描述
我想创建具有“名称”和“性别”属性的“人类”类。我想将“性别”属性的分配限制为“男性”或“女性”。为此,我们重写了 __setattr__ (self, name, value)。
class Human(object):
def __setattr__(self, name, value):
if name == 'gender':
if value in ('male', 'female'):
self.gender = value
else:
raise AttributeError('Gender can only be "male" or "female"')
h = Human()
h.name = 'Sweety'
h.gender = 'female'
print(h.gender)
但我得到以下例外:
[Previous line repeated 328 more times]
File "/Users/admin/algorithms/betright_test.py", line 143, in **__setattr__**
if name == 'gender':
RecursionError: maximum recursion depth exceeded in comparison
但是如果我传递了错误的性别(h.gender = 'f'),它会给我正确的错误(AttributeError:性别只能是“男性”或“女性”)
当我通过正确的性别时,我无法弄清楚出了什么问题。
解决方案
问题是您的__setattr__
函数包含在无限循环self.gender =
中调用的 ...行。__setattr__
您需要使用超类方法存储属性而不递归调用:__setattr__
super().__setattr__(name, value)
另请注意,在您的示例代码中,如果您尝试打印 h.name,您会得到一个 AttributeError,因为您的__setattr__
函数从未设置该属性。所以你想要的是这样的:
def __setattr__(self, name, value):
if name == 'gender':
if value not in ('male', 'female'):
raise AttributeError('Gender can only be "male" or "female"')
super().__setattr__(name, value)
推荐阅读
- mysql - Mysql:将行数乘以注册列
- python - 烧瓶错误 - jinja2.exceptions.TemplateNotFound
- html - 使 2 个 div 响应但仍在移动设备上,它们会跳起来
- ios - UIResponder 链在 UIButton 操作中不起作用
- python - ML- 如何拆分后续图像数据集?
- swift - 如何使用相同的变量线程安全地制作多个函数
- php - HTML表格结果全部返回一行
- sql - 使用 PyRFC 直接运行 SQL 查询
- angular - Bootstrap 下拉菜单在 Angular 中不起作用
- docker - 如何将文件复制到 docker 映像?