Python: 引用本地变量时未赋值错误

2 投票
3 回答
1815 浏览
提问于 2025-04-17 19:39

我一直遇到这个错误:

UnboundLocalError: 在赋值之前引用了局部变量 'new_speedDx'

这个错误出现在我尝试运行以下函数时:

def new_speedD(boid1):
    bposx = boid1[0]
    if bposx < WALL:
        new_speedDx = WALL_FORCE
    elif bposx > WIDTH - WALL:
        new_speedDx = -WALL_FORCE

    bposy = boid1[1]
    if bposy < WALL:
        new_speedDy = WALL_FORCE
    elif bposx > WIDTH - WALL:
        new_speedDy = -WALL_FORCE

    return new_speedDx, new_speedDy

在这个函数中,boid1 是一个包含 4 个元素的向量(x坐标,y坐标,x速度,y速度),而所有大写的变量都是常量(数字)。 有没有人知道该怎么解决这个问题?我在网上找到了很多可能的解决方案,但似乎都不管用……

3 个回答

2

解释

正如其他人提到的,你没有处理这种情况:WALL <= pos <= WIDTH - WALL

推荐的修改

假设小鸟在没有撞到墙的时候会继续保持当前的速度。有些代码会在小鸟没有撞到墙时把速度设为0。而这个解决方案的特点是使用了现有的速度。我觉得这对你的情况很重要。

代码

def new_speedD(boid1):
    def new_speed(pos, velocity):
        return WALL_FORCE if pos < WALL \
            else (-WALL_FORCE if pos > WIDTH - WALL \
            else velocity)
    xpos, ypos, xvelocity, yvelocity = boid1
    new_speedDx = new_speed(posx, xvelocity)
    new_speedDy = new_speed(posy, yvelocity)
    return new_speedDx, new_speedDy

有些人觉得这段代码难以理解。这里有个简单的解释:

  1. 如果位置小于墙的位置,就返回 WALL_FORCE。
  2. 否则,如果位置大于宽度减去墙的位置,就返回 -WALL_FORCE。
  3. 否则,返回当前的速度。

这里有一个关于三元运算符的一般性问题。不过要记住,有些 Python 爱好者不太喜欢这样用。

如果你不使用这段代码……

回到你原来的代码,修正 yvelocity 的拼写错误:bposx > WIDTH - WALLyvelocity 不依赖于 xpos

4

如果这两个条件都不成立,会发生什么呢?

if bposx < WALL:
    new_speedDx = WALL_FORCE
elif bposx > WIDTH - WALL:
    new_speedDx = -WALL_FORCE

... new_speedDx 就不会被赋值,所以它的值是无法确定的。

你可以通过指定在这种情况下 new_speedDx 应该是什么来解决这个问题:

if bposx < WALL:
    new_speedDx = WALL_FORCE
elif bposx > WIDTH - WALL:
    new_speedDx = -WALL_FORCE
else:
    new_speedDx = 0.
5

bposx 的值不能小于 WALL,也不能大于 WIDTH - WALL。

比如:

bposx = 10
WALL = 9
WIDTH = 200

if bposx < WALL:    # 10 is greater than 9, does not define new_speedDx 
    new_speedDx = WALL_FORCE
elif bposx > WIDTH - WALL:   # 10 is less than (200 - 9), does not define new_speedDx
    new_speedDx = -WALL_FORCE

因为没有看到你程序的其他部分,所以很难给出一个合适的备用值。不过,你可能需要加一些类似下面的代码:

else:
    new_speedDx = 0

撰写回答