Python:我可以替换字典中的对象吗?

时间:2014-07-03 13:16:23

标签: python arrays dictionary

我在覆盆子pi上使用Python中的pi3d lib。我要做的是动态创建屏幕对象,并替换它们。 首先,我想填写一系列字典。这些可以是整数,字符串或pi3D精灵对象。 我有以下测试代码:

import pi3d

DISPLAY = pi3d.Display.create(x=0, y=0)
shader = pi3d.Shader("uv_flat")
CAMERA = pi3d.Camera(is_3d=False)

screen_items=[]

for item_number in range (5):
    screen_item={}
    screen_item['type']= 'second_rotation_stepped'
    screen_item['text_type']='static'
    screen_item['visible']='always'
    screen_item['image_sprite']=pi3d.ImageSprite(pi3d.Texture("textures/PATRN.PNG", blend=True), shader, w=100.0, h=100.0, z=5.0 ,x=0,y=120*item_number)
    screen_items.append(screen_item)

screen_items[0]['image_sprite']=pi3d.ImageSprite(pi3d.Texture("textures/altimeter.png", blend=True), shader, w=50.0, h=50.0, z=5.0 ,x=0,y=-200)
screen_items[0]['visible']='never'
screen_items[2]['image_sprite'].rotateToZ(45)

mykeys = pi3d.Keyboard()



while DISPLAY.loop_running():
    for drawitem in screen_items:
        drawitem['image_sprite'].draw()

    if mykeys.read() == 27:
        mykeys.close()
        DISPLAY.destroy()
        Break

一切都按照我的预期运作,但它给了我一个错误/警告: “无法设置删除”

如果我阻止代码,则不会出现此错误:

screen_items[0]['image_sprite']=pi3d.ImageSprite(pi3d.Texture("textures/altimeter.png", blend=True), shader, w=50.0, h=50.0, z=5.0 ,x=0,y=-200)

我的代码不会出现此错误:

screen_items[0]['visible']='never'

所以我想我可以替换字典中的字符串,但不能替换对象? 就像我说的,一切正常,对象确实被替换(并在屏幕上绘制)但不知何故“旧”对象不会被删除。它是某种指针问题吗?

2 个答案:

答案 0 :(得分:1)

"错误"您尝试删除脚本中for循环中创建的初始Texture对象时,pi3d实际上是一个调试消息。

当您将新的ImageSprite对象重新分配给screen_items[0]['image_sprite']时,旧的Texture对象会被垃圾回收,并调用它的__del__方法,导致此问题调试消息。

参考:https://github.com/tipam/pi3d/blob/master/pi3d/Texture.py#L87

答案 1 :(得分:0)

这个问题起源是因为python垃圾收集器没有整理创建Texture实例时分配的gpu内存。

在python中,可以使用__del__()方法作为析构函数,但它不一定立即执行。当第一次观察到gpu缓冲区内存泄漏时,它被a bug in the video core due to implementation of EGL混淆了,所以pi3d最终得到了一条腰带和大括号'系统,其中引用在Display对象中保存到所有纹理,顶点和元素缓冲区,如果在关闭时,任何这些都没有被python对象释放。 __del__()方法,最终明确了。

然而,在某些情况下,非常偶然地,当程序关闭时,引用指向在它们可以删除对自己的引用之前已经释放的对象。由于这个bug对运行代码没有任何影响,因此很难理清它已经被放在了后面。

PS请参阅raspberry pi论坛帖子t = 79383,以便我解决@ satoer的问题