使用@property+setter封装账户编号时触发无限递归的原因?
解析@property实现中触发无限递归的原因
你遇到的无限递归问题,根源在于@property的实现逻辑错误,没有区分属性的实际存储变量和访问器方法:
问题代码
class SingleBankAccount: def __init__(self, account_number, account_balance): self.account_number = account_number self.account_balance = account_balance @property def account_number(self): return self.account_number @account_number.setter def account_number(self, number): # if there is a number already, raise exception, otherwise set it if self.account_number: raise AccountException("Someone tried to change the account number!") else: self.account_number = number
报错信息
File "main.py", line 17, in account_number if self.account_number: File "main.py", line 13, in account_number return self.account_number File "main.py", line 13, in account_number return self.account_number File "main.py", line 13, in account_number return self.account_number [Previous line repeated 993 more times] RecursionError: maximum recursion depth exceeded
递归原因详解
Getter方法的无限递归
当你用@property装饰account_number方法后,self.account_number不再是直接访问实例属性,而是会调用这个getter方法。而你的getter里写了return self.account_number,这会再次调用getter方法,形成无限循环,直到触发Python的递归深度限制。Setter方法的双重递归
在setter方法中存在两处递归触发点:- 判断
if self.account_number:时,会调用getter方法,再次进入递归循环 - 执行
self.account_number = number时,会调用setter方法本身,同样形成递归
- 判断
本质问题是:你没有用一个独立的变量来存储account_number的实际值,而是直接在getter/setter里操作同名的"属性",而这个"属性"其实是被@property包装后的方法,导致每次访问或赋值都在调用方法自身。
修复方案
使用下划线开头的私有变量(比如_account_number)存储实际值,getter和setter操作这个私有变量,避免递归:
class AccountException(Exception): pass class SingleBankAccount: def __init__(self, account_number, account_balance): self._account_number = account_number self.account_balance = account_balance @property def account_number(self): return self._account_number @account_number.setter def account_number(self, number): if self._account_number: raise AccountException("Someone tried to change the account number!") else: self._account_number = number
这样外部通过account_number属性访问时,会自动调用getter/setter,而内部存储用_account_number,不会触发递归,同时实现了禁止修改账号的需求。
内容的提问来源于stack exchange,提问作者Alejandro Veintimilla
相关产品推荐
相关产品推荐

