Python: локальная переменная, на которую ссылаются до ошибки присваивания

Я продолжаю иметь ошибку

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 элементами (xpos, ypos, xvelocity, yvelocity), а все переменные в верхнем регистре являются константами (числами). У кого-нибудь есть идеи, как это решить? Я нашел много возможных решений в интернете, но ничего не получалось..

3 ответа

Должно быть, что 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

Что происходит, если ни одно из этих условий не выполняется?

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.

объяснение

Как уже отмечали другие, вы не имеете дело с делом, которое 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, если pos
  2. в противном случае вернуть -WALL_FORCE, если pos > WIDTH - WALL
  3. в противном случае скорость возврата

Вот общий вопрос о троичном операторе. Вспомни, подумал, что "Это осуждается некоторыми питонистами".

Если вы не используете этот код...

Вернитесь к оригиналу и исправьте опечатку в yvelocity дело: bposx > WIDTH - WALL, yvelocity не зависит от xpos,

Другие вопросы по тегам