【发布时间】:2014-12-23 20:03:24
【问题描述】:
我有一个大的 2D(列表列表)列表,每个元素都包含一个整数、字符串和字典的列表。我希望能够确定任何被修改的元素的“路径”(例如 [2][3][2]["items"][2]!),并在修改时触发.这个列表太大了,可以浏览一下,看看有什么变化!理想情况下,我还想要一份新元素的副本,尽管稍后可以找到。
我的第一次尝试是创建一个类,并覆盖它的__setattr__ 方法:
class Notify():
def __setattr__(self, name, value):
self.__dict__[name] = value #Actually assign the value
print name, value #This will tell us when it fires
然而,__setattr__ 方法仅在设置一个不被索引(或键)访问的变量时触发,因为这似乎将调用外包给包含的 list()/dict() 类而不是我们的类。
>>> test = Notify()
>>> test.var = 1 #This is detected
var 1
>>> test.var = [1,2,3] #Now let's set it to a list
var [1, 2, 3]
>>> test.var[0] = 12 #But when we assign a value via an index, it doesn't fire
>>> test.var
[12, 2, 3] #However it still assigns the value, so it must be talking to the list itself!
所以,总而言之,我想要(任何方法)告诉我在什么(索引/键列表)发生了变化,并且这需要在发生时发生,因为扫描整个过程太昂贵了列表。我也不能依赖修改列表的代码来提供详细信息。如果这对于第 n 个嵌套列表是不可能的,我可以使用只给出前两个索引的东西,因为那里的数据不会太大而无法扫描。提前感谢您的帮助!
编辑:虽然这个问题Track changes to lists and dictionaries in python? 似乎很接近我的需要,但仍然没有乐趣。不幸的是,我的课程不是很好,需要有人的帮助!
编辑:看了这个Python: Right way to extend list 让我觉得继承list 可能是个坏主意。我使用代理类提出了以下代码。然而,最初的问题仍然存在,对嵌套列表的修改不会记录。类组合而不是继承是个好主意吗?
from UserList import UserList
class NotifyList(UserList):
def __init__(self, initlist=None):
self.data = []
if initlist is not None:
if type(initlist) is list:
self.data[:] = initlist
elif isinstance(initlist, NotifyList):
self.data[:] = initlist.data[:]
else:
self.data = list(initlist)
def __setitem__(self, key, item):
if type(item) is list:
self.data[key] = NotifyList(item)
else:
self.data[key] = item
print key, item
def append(self, item):
if type(item) is list:
self.data.append(NotifyList(item))
else:
self.data.append(item)
print self.index(item), item
【问题讨论】:
-
也许您可以签入
__setattr__值的类型,如果它是一个列表,您可以将其包装在 Notify 对象中? -
另外,您可以向 Notify 类添加一些功能,例如父类,因此如果值更改并且 Notify 类不是根,它可以向上传递事件
-
或许this的回答可能对你有所帮助。
-
@lelloman 我对 python 中的类很陌生,但是新对象的新通知类仍然会像那些对象一样(仍然有 .append() 用于列表等)吗?
-
@Mauro Baraldi 谢谢,这看起来像我需要的 - 我怎么没找到!?