Python类实例使用+=操作符后变为None的原因及解决方法
问题原因分析与解决方法
嘿,这个问题我之前踩过同款坑,咱们一步步拆解来看:
为啥用__add__实现+=后,实例变成None了?
当你用+=操作符时,Python的处理逻辑是这样的:
- 先找对象有没有
__iadd__方法(专门处理原地加法的); - 如果没找到,就退而求其次调用
__add__,然后把__add__的返回值重新赋值给原来的变量。
你的__add__方法只做了self.lItems.append(other),但没写返回值——Python里函数默认返回None。所以执行problem += 'text'就相当于:
problem = problem.__add__('text')
这可不就把None赋值给problem了嘛,打印出来自然是None。
为啥你试的__iadd__没效果?
十有八九是你的__iadd__没返回self!__iadd__的核心要求就是必须返回修改后的实例本身,光在内部改列表但不返回的话,同样会导致赋值后变量变成None。
正确的实现姿势
姿势1:同时支持+和+=(一个新建实例,一个原地修改)
如果你想让+生成新实例,+=原地修改,就得把两个方法都写对:
class Problem: def __init__(self): self.lItems = [] # 普通加法:返回新实例,不修改原对象 def __add__(self, other): new_problem = Problem() new_problem.lItems = self.lItems.copy() # 复制原有列表避免关联 new_problem.lItems.append(other) return new_problem # 原地加法:修改自身后必须返回self def __iadd__(self, other): self.lItems.append(other) return self # 自定义打印内容,方便看结果 def __repr__(self): return f"Problem(lItems={self.lItems})" # 测试一下 problem = Problem() problem += 'text' print(problem) # 输出: Problem(lItems=['text']) new_problem = problem + 'another' print(new_problem) # 输出: Problem(lItems=['text', 'another']) print(problem) # 原实例没变: Problem(lItems=['text'])
姿势2:只需要原地修改的+=
如果不需要支持普通的+操作,那只把__iadd__写对就行:
class Problem: def __init__(self): self.lItems = [] def __iadd__(self, other): self.lItems.append(other) return self # 这行绝对不能少! def __repr__(self): return f"Problem(lItems={self.lItems})" problem = Problem() problem += 'text' print(problem) # 输出: Problem(lItems=['text'])
小提示
别忘了加个__repr__或者__str__方法,不然直接打印实例会显示一堆内存地址,根本看不到里面的列表内容~
内容的提问来源于stack exchange,提问作者mrCarnivore
相关产品推荐
相关产品推荐

