假设我有一个Snit
:
class Snit(): pass
以及一个Snot
,它包含多达四个Snit
的弱引用:
我还有一个Snot
工厂:
以及Snit
的list
(原为asnit_list
):
snit_list = []
for i in range(12):
snit_list.append(Snit())
现在,我使用我的snit_list
中的Snit
列出Snot
:
snot_list = []
for i in range(3):
snot_list.append(snot_factory(snit_list[4*i],snit_list[4*i+1],snit_list[4*i+2],snit_list[4*i+3]))
哎呀!我不再需要snit_list[3]
,因此我将继续删除它:
snit_list.pop(3)
但现在我有一个Snot
和一个死人在一起Snit
:
snot_list[0].s4 # <weakref at 0x00BlahBlah; dead>
这不能忍受!一个死了的Snot
显然是完全无稽之谈。在
所以我真的希望任何对Snot
的引用,至少在它的一个或多个Snit
被销毁后返回为None
。但在理想情况下,最好将Snot
从snot_list
列表中自动删除(len(snot_list)
会因删除的Snot
个数而缩小)。在
这样做的好方法是什么?在
Snot
是一个仅当存在一组有效的Snit
s时才应存在的对象(“valid”表示它具有与初始化时相同数量的已定义的Snit
),其行为如下:
Snot
中的任何一个Snit
消失了(当没有强引用保留时),Snot
也应该消失(这就是为什么我将s1
,s2
等设置为弱引用的原因)。请注意,Snot
可能已经用4、3、2或1^{Snit
的数目无关紧要,^{Snot
包含对Snit
的引用消失,则{Snot
时,包含对Snot
对象的引用的数据结构也会更新(Snot
得到{Snit
的Snots
都不存在时,Snit
也会消失,任何包含{Snit
得到{因此,理想的解决方案将允许我设置一些东西,以便我可以编写如下代码:
snits = get_snits_list(some_input_with_10000_snits)
snots = get_snots_list(some_cross_referenced_input_with_8000_snots)
#e.g.: the input file will say:
#snot number 12 is made of snits 1, 4, 7
#snot number 45 is made of snits 8, 7, 0, 14
do_stuff_with_snits()
snits.pop(7) #snit 7 is common to snot 12 and 45
assert len(snots) == 7998 #snots 12 and 45 have been removed
但是,如果这太难了,我可以:
assert snots[12] == None
assert snots[45] == None
我愿意改变一些事情。例如,如果这使设计更容易,我认为最好删除对Snit
s的弱引用,或者将它们移到Snit
的列表中,而不是让Snot
成员成为弱引用(尽管我看不出这两个更改如何改进)。在
我还考虑过创建Snot
子类-ClearSnot
,用1Snit
,YellowSnot
用2Snit
,用3Snit
创建{
好的,你有一个
Snot
,变量是Snit
s实际上,让类实例消失将需要更多的工作(例如让
dict
在类上跟踪它们,然后其他数据结构将只使用弱引用,但这可能会很快变得难看),所以下一个最好的方法是当它的任何一个Snit
消失时,它就等于None
。在我知道}都是}实际上从数据结构中删除了,但这会增加复杂性:每个}中,这可能会导致其他问题。。。在
snits
和{list
,顺序重要吗?如果顺序不重要,可以使用set
s,这样就有可能有一个性能解决方案,其中死的{Snot
必须跟踪它所在的数据结构,并且每个Snit
必须保留一个列表,其中Snot
它在里面,而魔法必须生活在{没有什么是真正自动的。您需要有一个手动运行的函数来检查死的}发生任何有趣的事情时,都会调用该函数来检查并删除死的
Snit
,或者有一个属于Snot
的函数,当{Snit
例如:
有趣的部分是添加对
_remove_dead_snits
的调用,以便与__getitem__
、__iter__
等_remove_dead_snits
的每个有趣的交互,以及您可以对它做的任何其他操作。在实际上,仔细考虑一下,如果每个
^{pr2}$Snot
只有四个可能的Snit
,那么可以使用一个SnitRef
描述符,下面是对原始代码的一些更改:跑步时:
相关问题 更多 >
编程相关推荐