我有一个 a 的实例,class
它作为一个元素出现在多个list
s 中。我想删除实例并同时将其从每个list
元素中删除。这可能吗?
问问题
74 次
2 回答
7
对此的一种回答是始终允许您放入列表中的对象管理列表成员资格。例如,而不是说
listA.append(objectA)
你会用
objectA.addToList(listA)
这将允许您在内部存储包含所有列表的列表objectA
。然后,当你想删除时objectA
,你需要调用这样的方法:
def cleanup(self):
for listToClean in myLists:
listToClean.remove(self)
但是,这确实对您的程序施加了一些严格的限制 - 例如,如果由这些列表之一制作副本,则对象将不会引用该副本。您必须假设列表的任何副本(不要忘记切片也是副本)可能包含过时的对象,这意味着您希望尽可能频繁地使用原始列表.
于 2014-03-21T20:25:11.350 回答
1
您可以考虑使用weakref.refs:
class WeakRefList(list):
def __init__(self, args):
list.__init__(self, [self.weak(item) for item in args])
def append(self, item):
list.append(self, self.weak(item))
def weak(self, item):
return weakref.ref(item, self.remove)
class Object(object):
def __init__(self, name):
self.name = name
orig = [Object('Foo'), Object('Bar')]
weaklist = WeakRefList(orig)
orig.append(Object('Baz'))
weaklist.append(orig[-1])
print(orig[0])
# <__main__.Object object at 0xb748aaac>
print(weaklist)
# [<weakref at 0xb7487a54; to 'Object' at 0xb748aaac>,
# <weakref at 0xb7487a7c; to 'Object' at 0xb748ab6c>,
# <weakref at 0xb7487aa4; to 'Object' at 0xb748ac2c>]
您调用weakref
来恢复原始对象。如果它不存在,则调用wearef
返回None
:
print(weaklist[0]())
# <__main__.Object object at 0xb748aaac>
它返回完全相同的对象:
print(orig[0] is weaklist[0](), id(orig[0]), id(weaklist[0]()))
# (True, 3074992812L, 3074992812L)
您可以照常访问其属性(或方法):
print(weaklist[0]().name)
# Foo
for item in weaklist:
print(item)
# <weakref at 0xb7487a54; to 'Object' at 0xb748aaac>
# <weakref at 0xb7487a7c; to 'Object' at 0xb748ab6c>
# <weakref at 0xb7487aa4; to 'Object' at 0xb748ac2c>
print([item.name for item in orig])
# ['Foo', 'Bar', 'Baz']
print([item().name for item in weaklist])
# ['Foo', 'Bar', 'Baz']
最后,这是您正在寻找的属性:从orig
自动删除项目也会自动删除它们weaklist
:
while orig:
item = orig.pop()
del item
print(orig)
# []
print(weaklist)
# []
于 2014-03-21T22:07:15.540 回答