Python自定义类调用__repr__触发AttributeError问题咨询
错误成因与修复方案
错误成因
__init__采用条件绑定属性的逻辑:仅传low时实例只会绑定low属性,仅传high时实例只会绑定high属性,两个属性不会同时存在。测试用例仅传入了high参数,所以实例没有low属性。- Python的
or短路逻辑生效的前提是左侧表达式可以正常求值,__repr__中直接写self.low or self.high时,第一步访问self.low就因为属性不存在抛出AttributeError,根本不会执行后续的or self.high逻辑。 - 额外隐藏问题:
__repr__中调用了str(self),如果没有自定义__str__方法,Python会默认调用__repr__,会触发无限递归死循环。
修复方案
方案1:统一初始化属性默认值(更推荐)
修改__init__逻辑,提前给两个属性赋值默认值,保证属性一定存在,or的短路逻辑可以正常生效,同时修复递归问题:
class MyClass(): def __init__(self, name, high=None, low=None): self.name = name # 提前初始化两个属性,避免属性不存在 self.low = low self.high = high if not low and not high: raise Exception("Not found") def __repr__(self): value = self.low or self.high # 用类名替代str(self),避免无限递归 return f'{self.__class__.__name__}({self.name}, {value})'
方案2:先判断属性存在再取值
如果不想修改__init__的条件绑定逻辑,可修改__repr__的取值逻辑:
def __repr__(self): # 先判断属性是否存在再取值 value = self.low if hasattr(self, 'low') else self.high return f'{self.__class__.__name__}({self.name}, {value})'
内容的提问来源于stack exchange,提问作者Pranava
相关产品推荐
相关产品推荐

