如何防止小部件之间共享属性?

时间:2016-04-27 20:58:24

标签: python kivy

我正在使用Kivy进行游戏,玩家可以按一个键来射击炸弹。这是一个简化的功能:

def shoot(self, world):
    # self is the player widget
    bomb = Bomb(pos=self.pos)
    world.add_entity(bomb)
有趣的是,当玩家射击时,无论他走到哪里,炸弹都随身携带。

调试后我意识到这是因为玩家和炸弹共享velocity属性。

Player类和Bomb类都继承Entity,它在类级定义velocity = ObjectProperty(Vector(0, 0))。在运行时调试显示两个对象引用完全相同的对象。

问题是,Kivy属性实际上应该在每个实例上创建单独的属性。那么为什么这个不需要的共享状态,我该如何解决这个问题?

解决方案

感谢@Tshirtman对this question的回答,我发现了问题和解决方案。

结果证明Kivy属性有一个问题,实例化它们时设置的初始值将由该类的所有实例共享。

澄清:

# this implementation results in the property shared by all instances

class MyWidget(Widget):
    my_field = ObjectProperty(MyObject())

w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field  # True

如您所见,my_field实际上是在两个实例之间共享的。

要避免此行为,除了设置类级属性外,还要确保在特定对象上设置属性。

例如:

class MyWidget(Widget):
    my_field = ObjectProperty()

    def __init__(self, **kwargs):
        super(MyWidget, self).__init__(**kwargs)
        self.my_field = MyObject()  # explicitly set the value on the object

w1 = MyWidget()
w2 = MyWidget()
w1.my_field is w2.my_field  # False    

当显式设置字段的值时,不在实例之间共享该字段。希望这有助于某人。

1 个答案:

答案 0 :(得分:0)

Kivy的小工具不会自动执行此操作,可能是您编写的代码无意中造成了这种情况。如果您需要帮助来跟踪它,请发布一个可运行的示例来演示问题。