Python 将元素添加到列表时运行代码
如何在列表中添加内容时进行检测?是否有一个等价于dictionaryPython 将元素添加到列表时运行代码,python,list,Python,List,如何在列表中添加内容时进行检测?是否有一个等价于dictionary\uuuuu setitem\uuuuuuuuuuuuuuuuuuuuuu的方法,当通过insert、extend、append或使用+=(\uuuuuuuuuuuuuuuuuuu add)、\uuuuuuud>或其他我可能忘记的方法将某些内容添加到列表中时,将调用该方法?或者我需要一个接一个地挂接这些方法吗?您需要分别覆盖每个方法。特别是您提到的操作性质不同-追加、插入、扩展、以及+=在创建新列表时修改列表 如果你觉得很新奇,
\uuuuu setitem\uuuuuuuuuuuuuuuuuuuuuu
的方法,当通过insert
、extend
、append
或使用+=
(\uuuuuuuuuuuuuuuuuuu add
)、\uuuuuuud>或其他我可能忘记的方法将某些内容添加到列表中时,将调用该方法?或者我需要一个接一个地挂接这些方法吗?您需要分别覆盖每个方法。特别是您提到的操作性质不同-追加
、插入
、扩展
、以及+=
在创建新列表时修改列表
如果你觉得很新奇,这是一种不必写太多样板的潜在方法:
class MyList(list):
pass
for method in ['append', 'insert', 'extend', '__add__', '__iadd__']:
def code_added(self, *args, **kwargs):
# Your code here
getattr(super(MyList, self), method)(*args, **kwargs)
setattr(MyList, method, code_added)
根据要运行的代码访问的内容,您可能需要分别处理\uuuu添加
。正如obskyr的回答所建议的那样,您必须定义列表的子类
,覆盖许多方法,并仔细测试以确定是否遗漏了某些内容
我的方法使用一个更深的钩子,使用\uuuu getattribute\uuuuu
(用于方法调用)、\uuuuu iadd\uuu
(用于+=
)和\uuuuuu setitem\uuuuuuu
(用于切片分配)来捕获最大的更改,并调用原始父方法,使其充当一个通用的中间人:
class MyList(list):
def __getattribute__(self,a):
if a in {"append","extend","remove","insert","pop","reverse","sort","clear"}:
print("modification by {}".format(a))
else:
print("not modified {}".format(a))
return list.__getattribute__(self,a)
def __iadd__(self,v):
print("in place add")
return list.__iadd__(self,v)
def __setitem__(self,i,v):
print("setitem {},{}".format(i,v))
return list.__setitem__(self,i,v)
l = MyList()
l.append(12)
l.extend([12])
l.remove(12)
print(l)
l[:] = [4,5,6]
l += [5]
print(l)
输出:
modification by append
modification by extend
modification by remove
[12]
setitem slice(None, None, None),[4, 5, 6]
in place add
[4, 5, 6, 5]
如你所见
列表已正确修改
检测到所有更改
我可能错过了一些访问,但这似乎离我很近。+=
不会创建新列表。@khelwood它确实创建了!然后它将它赋给变量,但它不是同一个对象。我可以看到你会怎么想,但它不是。试试看。@obskyr你把它和字符串或其他不可变对象的+=
混为一谈了。列表是可变的,因此这与.extend
(除此之外,你的答案是最好的ATM:)@Jean-Françoisfar-Huh,你说得对!它没有调用extend
,但它确实修改了列表。不禁注意到您将成员资格测试从一个集合更改为一个列表-有什么理由不使用集合吗?没有,只是我改进了编辑框中的集合内容,但用+=改进粘贴了我的旧代码。虽然我的需要有点过头了,我喜欢它既聪明又可读。你的需求很重要,但为你的问题提供一个深思熟虑的答案也很重要(对于未来的读者来说,可能要求更高)