这是我的情况:

我有一个要在其上调用list/set函数的movieplayer对象的"preload"(无关紧要)。该预加载函数可以立即返回,但将来希望返回一点。

我想存储这个电影播放器​​的集合,指示它们尚未预加载,然后遍历它们,调用preload函数。 preload函数在返回时会将它们从集合中删除(所以我会知道它们何时都已预加载)。

但是,我认为因为python正在等待preload函数,然后删除播放器,所以我得到了set size changed during iteration error

嘿是我的代码的简化版本,我希望能找到一种解决此问题的方法。

a = set([mp1, mp2 mp3])
for player in a:
    preload(player)

# preload would be something like
def preload(player):
    player.preloadVideo()
    a.remove(player)
    # This is where I believe the error gets generated.


我能想到的唯一解决方案是对copy制作一个set a,然后对其进行迭代,但是我不确定这是否是正确的方法,甚至无法奏效。

最佳答案

您可以通过遍历集合的副本来修复它。我在这里使用list()

a = set(['mp1', 'mp2', 'mp3'])

# preload would be something like
def preload(player):
    player.preloadVideo()
    a.remove(player)

for player in list(a):
    preload(player)    # N.B. pass player, not a


但是,这不是一个好的设计。一方面,全局变量a是从preload()函数中引用的。此外,for循环遍历集合中的所有元素,依次将每个元素传递给preload(),因此不必检查player中每个a的成员资格。最后,preload()应该执行预加载播放器所需的所有操作,但它不负责维护外部数据结构(a)。

更好的设计是使preload()返回一个布尔值,该布尔值指示预加载是否成功。然后可以在预加载功能之外删除成功加载的播放器:

a = set(['mp1', 'mp2', 'mp3'])

# preload would be something like
def preload(player):
    return player.preloadVideo()    # assume that this returns boolean

for player in list(a):
    if preload(player):
        a.remove(player)

if len(a):
    print "{} player(s) failed to preload: {}".format(len(a), a)
else:
    print "All players successfully preloaded"


此代码仅在成功预加载播放器后将其删除。

09-25 22:09