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
Некоторые думают, что этот код трудно понять. Вот краткое объяснение:
- вернуть WALL_FORCE, если pos
- в противном случае вернуть -WALL_FORCE, если pos > WIDTH - WALL
- в противном случае скорость возврата
Вот общий вопрос о троичном операторе. Вспомни, подумал, что "Это осуждается некоторыми питонистами".
Если вы не используете этот код...
Вернитесь к оригиналу и исправьте опечатку в yvelocity
дело: bposx > WIDTH - WALL
, yvelocity
не зависит от xpos
,