Python в функции не видит переменную в глобальной области

test_list = [1, 3, 4]


def test_func():
    test_list = test_list
    return test_list


print(test_func())

У меня в глобальной области видимости есть переменная 'test_tuple'. В функции 'test_func' хочу создать локальную переменную с таким же названием, как и в глобальной области.

Получается ошибка:

 test_list = test_list
UnboundLocalError: local variable 'test_list' referenced before assignment

Вопрос: Python вычисляет выражения справа налево. Справа он увидел переменную, которой нет в локальной области видимости - значит Python идет в глобальную область видимости, берет переменную и создает локальную переменную с таким же названием. Почему в моем примере это не так? Почему Python пытается изменить глобальную переменную, хотя должен создать локальную? Заранее спасибо.


Ответы (2 шт):

Автор решения: MarianD

Когда бы вы написали вашу функцию в виде

def test_func():
    test_list_new = test_list
    return test_list_new

или просто

def test_func():
    return test_list

все бы было в порядке. Объясню, почему, и почему ваш код выдает ошибку.

Проблема состоит в том, что вы начали во внутри определения функции писать

    test_list =

Когда интерпретатор Питона видит на левой стороне команды присваивания переменную, которая не находится ни во внутри определения функции, ни в списке параметров, он старается создать ее как новую переменную, несмотря на то, если переменная с таким именем существует вне определения функции.*)

(Почему? Потому, что Питон стандартно не позволяет изменить значение внешней переменной из внутри функции.)

Значит, у вас бы могли быть 2 переменные с тем же самым именем test_list, которые бы никаким образом не были взаимно связаны. В первой из них уже значение [1, 3, 4], вторую — которая пока не существует — вы хотите создать командой присваивания test_list = test_list.

Когда бы на правой стороне было что-то уже определено, все бы было в порядке и (внутренняя) переменная test_list бы создана выла. Но на правой стороне то же самое имя - т.е. имя переменной, которая пока не была создана.

И об этом говорит (на английском) ваше сообщение об ошибке.


*) Когда бы переменная test_list не находилась внутри определения функции ни разу на левой стороне команды присваивания, новая переменная бы создана не была — как в моих примерах кода.

Внешнюю переменную можно в функции только читать, но не в нее записывать.

→ Ссылка
Автор решения: Noskill
def test_func(test_list):
    return test_list
→ Ссылка