tg-me.com/pyproglib/6606
Last Update:
UnboundLocalError
Сегодня разбираем одну из тех ошибок в Python, которая выглядит загадочно, но легко объяснима, если знать одну тонкость.
💥 Что произошло
def trigger(*fns):
def decorator(fn):
fn._next = fns
def _wrapper():
fn()
for f in fn._next:
f()
return _wrapper
return decorator
def step_2():
print("step 2")
def step_3():
print("step 3")
@trigger(step_2, step_3)
def step_1():
print("step 1")
step_1()
Вывод:
step 1
step 2
step 3
fn
снаружи:def _wrapper():
fn()
for fn in fn._next: # ❗️ shadowing
fn()
UnboundLocalError: cannot access local variable 'fn' where it is not associated with a value
❓ Почему так
В Python, если переменная где-то присваивается в функции — она считается локальной на весь скоуп этой функции. Даже если вы пытаетесь её использовать до присваивания.
fn
переопределяется в цикле, а значит, Python считает, что она локальная для всей _wrapper()
. Поэтому вызов fn()
выше в коде — обращение к переменной, которой ещё нет, отсюда и UnboundLocalError
.На заметку:
Просто не переименовывайте переменную в
fn
повторно. Назовите её f
, next_fn
, step
, callback
— что угодно:for step in fn._next:
step()
💬 Вопрос к вам: какие ошибки Python вам кажутся самыми «обидными», но по факту — обучающими?
Библиотека питониста #буст