Рассмотрим следующий пример:
>>> lst = [1, 2, 3]
>>> def foo1():
... lst.append(5) # работает нормально ...
...
>>> foo1()
>>> lst
# [1, 2, 3, 5]
>>> lst = [1, 2, 3]
>>> def foo2():
... lst += [5] # выдает ошибку ...
...
>>> foo2()
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 2, in foo
# UnboundLocalError: local variable 'lst' referenced before assignment
Разбираемся почему вызов функции foo2()
выдает исключение, а foo1()
работает нормально?
Ответ более тонкий и кроется в области видимости глобальной переменной
списка lst
в локальной области функции
foo2()
.
Функция
foo1()
не ПРИСВАИВАЕТ значение списку
lst
, а просто расширяет его содержимое методом
.append()
, тогда как функция
foo2()
пытается расширить список задействовав саму переменную
lst
. Согласно
правилам видимости переменных, в локальной области можно прочитать глобальную переменную, а при попытке присвоения, интерпретатор будет искать ее в локальной области функции, где она еще не определена и выдаст ошибку
UnboundLocalError
.
Выражение lst + = [5]
на самом деле является сокращением для lst = lst + [5]
, следовательно происходит присвоение значения списку lst
. Но значение, которое мы хотим присвоить lst
, основано на самом lst
, которое в локальной области функции foo2()
еще не было определено.