Kivy官方Pong教程 - Vector的使用(kivy.vector)

时间:2014-08-17 17:46:40

标签: python kivy

我一直在关注官方的Kivy PongApp教程(link - 网站底部的整个程序代码),我遇到了一个我无法理解的问题。

我已经定义了移动功能,通过每帧上的速度矢量来改变球的位置。代码:

def move(self):
    self.pos = Vector(*self.velocity) + self.pos

然而,当我编写这样的代码时:

def move(self):
    self.pos = self.pos + Vector(*self.velocity)

导致错误: ValueError:PongBall.pos值长度是不可变的

为什么,不应该一样吗?

2 个答案:

答案 0 :(得分:6)

self.poskivy.properties.ObservableReferenceList

当您尝试设置此属性时,它会检查以确保新值与旧值的长度相同。

来自kivy.properties.ReferenceProperty

cdef check(self, EventDispatcher obj, value):
  cdef PropertyStorage ps = obj.__storage[self._name]
  if len(value) != len(ps.properties):
    raise ValueError('%s.%s value length is immutable' % (
      obj.__class__.__name__, self.name))

此外,kivy.properties.ObservableList子类list

不幸的是,kivy.vector.Vector也是如此,并且任何具有Python经验的人都可以告诉你,list.__add__连接它的论点。

这意味着通过扩展将向量添加到self.pos,而不是通过元素添加向量,这会导致self.pos抱怨,因为它的长度正在发生变化。

它的另一种方式是aronud,因为Vector overloads __add__可以进行元素添加。

因为python偏爱__add__超过__radd__,所以整个事情都失败了。

答案 1 :(得分:4)

我认为这只是因为Vector类型会覆盖添加以执行向量添加,并且在第一种情况下调用其__add__,它会自动将self.pos(列表)视为另一个向量。

在第二种情况下,调用self.pos的__add__,它不知道Vector类型,而是尝试执行扩展列表长度的正常列表添加。这会因您看到的错误而失败,因为pos必须是固定长度的列表。

总的来说(如果我是对的),问题是+根据其参数的类型做不同的事情。这通常并不重要,但恰好在这里发挥重要作用。