Python继承list子类自定义append方法原地修改失效问题
问题原因
Python实例方法内的self本质是指向当前实例的局部变量,对self本身做重新赋值,只会修改当前方法作用域内的变量指向,不会对原始实例对象做任何改动。
你写的append_方法中,实际逻辑是创建了一个全新的MyList实例,再让局部的self指向这个新实例,从头到尾没有修改最初创建的my_list实例绑定的列表数据,因此原对象不会发生变化,只有方法返回值是你新建的那个副本对象。
修复方案
根据你想要的行为二选一即可:
方案1:和原生append一致,原地修改原对象
如果需要append_调用后直接修改原列表,直接调用父类list的原生原地追加方法即可,不需要创建新对象:
class MyList(list): def append_(self, element): # 直接修改当前实例存储的列表内容 self.append(element) # 如果需要支持链式调用可以保留return self,否则可以删掉,和原生append一样返回None return self
测试效果:
my_list = MyList(range(5)) print(my_list.append_(6)) # 输出 [0, 1, 2, 3, 4, 6] print(my_list) # 输出 [0, 1, 2, 3, 4, 6],原对象被正确修改
方案2:不修改原对象,返回追加元素后的新列表
如果你想要的是不可变风格的方法(调用后原列表不变,返回新列表),不需要给self赋值,直接返回创建好的新对象即可,调用时需要用变量接收返回值:
class MyList(list): def append_(self, element): new_list = self.copy() new_list.append(element) return self.__class__(new_list)
测试效果:
my_list = MyList(range(5)) new_list = my_list.append_(6) print(my_list) # 输出 [0, 1, 2, 3, 4],原对象保持不变 print(new_list) # 输出 [0, 1, 2, 3, 4, 6],返回值是追加后的新对象
注:所有修改实例本身的操作,都需要直接对
self持有的属性/数据做原地修改,而非给self变量重新绑定新对象。
内容的提问来源于stack exchange,提问作者FraSchelle
相关产品推荐
相关产品推荐

