Python字典通过迭代交换元素值

时间:2019-02-25 14:55:32

标签: python dictionary memory-leaks

问题

我正在构建像python这样的视频编辑器。我创建了使用字典存储动画对象的时间轴。当我进入渲染阶段时,我必须渲染电影,这是场景的重要时间轴,也是时间轴。因此,每部电影至少有2本字典。当我遍历场景时,我遍历字典并渲染场景:

timeline = self.tl.timeline_object.items() # get the items of the dictionary
for scene in timeline:
    print(timeline, id(timeline))
    scene[1]()                             # do all the render stuff

给出以下结果:

dict_items([('1', <class 'test_movie.first_scene.FirstScene'>), ('2', <class 'test_movie.second_scene.SecondScene'>)]) 140043388706584
dict_items([('1', <animations.FillScreen.FillScreen object at 0x7f5e643a67f0>), ('2', <animations.Write.Write object at 0x7f5e643a69b0>)]) 140043388706584

您会看到电影的一部和场景的一部之间的字典交换(请看ID)。

我应该得到第一行:

dict_items([('1', <class 'test_movie.first_scene.FirstScene'>), ('2', <class 'test_movie.second_scene.SecondScene'>)]) 140043388706584

第二次迭代。

问题

为什么我要获取场景的字典而不是存储在timeline中的“真实”字典?以及如何解决这个问题?

PLUS:完整代码

代码很长,涉及很多对象,我试图向您展示最大数量而不会失去您。如果您要实际回购:https://gitlab.com/planchon/psVidTex

否则,这是重要文件:

class MovieName(Movie):
    def __init__(self):
        Movie.__init__(self)

    # add the scene to the movie timeline (dictionnary + time array)
    def prepare(self):
        self.add_to_timeline(FirstScene, 0, 10)
        self.add_to_timeline(SecondScene, 10, 20)
class Timeline(object):
    timeline_object = {}
    timeline        = []
    timeline_index  = []

    max_id = 0

    def __init__(self):
        pass

    # ajoute un element dans la timeline retourne la timeline_id de l'object
    # prend des frames comme unité de mesure du temps
    def add_object(self, animation, start, end, position):
        animation_id = self.get_global_id()
        self.timeline_object[animation_id] = animation                      
        self.add_into_timeline(start, [start, end, position, animation_id]) 

        return animation_id

    # add the tuple [start, end, position, animation_id] into the timeline
    def add_into_timeline(self, start, element):
        index = bisect.bisect(self.timeline_index, start)
        self.timeline_index.insert(index, start)
        self.timeline.insert(index, element)

    # get the next id
    def get_global_id(self):
        self.max_id = self.max_id + 1
        return str(self.max_id)
class FirstScene(Scene):
    def __init__(self):
        Scene.__init__(self)

    def prepare(self):
        self.add_to_timeline(FillScreen("col"), 0, 10)
        self.add_to_timeline(Write("test"), 0, 10)
class Movie(object):
    tl = Timeline()

    def __init__(self):
        self.prepare()
        self.init_all_scene()

    def render(self):
        pass

    def prepare(self):
        pass

    def init_all_scene(self):
        timeline = self.tl.timeline_object.items()
        for scene in timeline:
            print(timeline, id(timeline))
            scene[1]()

    # add the scene to the timeline
    def add_to_timeline(self, scene, start, end):
        return self.tl.add_object(scene, start, end, 0)
class Scene(Container):
    tl = Timeline()

    def __init__(self, **kargs):
        self.prepare()

    def add_to_timeline(self, anim, start, end):
        return self.tl.add_object(anim, start, end, 0)

    def prepare(self):
        pass

    def render(self):
        pass

在这种情况下,WriteFillScreen不是相关对象。您可以根据需要在存储库中找到它们。

1 个答案:

答案 0 :(得分:0)

问题是时间轴类未正确初始化,并且timeline_object在所有不同的时间轴之间共享。

要解决,我刚刚修改了时间轴类:

class Timeline(object):    
    def __init__(self):
        self.timeline_object = {}
        self.timeline        = []
        self.timeline_index  = []
        self.max_id          = 0

通过更改数组在init中的位置,使它们位于对象本地,而不是元对象...