3

我有一个 a 的实例,class它作为一个元素出现在多个lists 中。我想删除实例并同时将其从每个list元素中删除。这可能吗?

4

2 回答 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 回答