Область видимости локальных переменных
Содержание курса
Исправление NameError через return и внешнюю переменную
Решение прямолинейное: если значение, вычисленное внутри функции, нужно снаружи — его нужно явно передать через return. Тогда вызывающий код получает это значение как результат вызова и может сохранить его в собственную переменную.
Возьмём сломанный код из предыдущего примера и исправим его по шагам.
Шаг 1.
Убедиться, что нужное значение действительно вычислено внутри функции. В нашем случае result = 42 — вычисление есть.
Шаг 2.
Добавить return с этим значением в конце функции:
def calc():
result = 42
return result
Шаг 3. В вызывающем коде сохранить результат вызова в переменную:
value = calc()
Теперь value — это обычная глобальная переменная. Она получила значение 42, которое calc() вернула через return. Переменная result при этом по-прежнему локальная и по-прежнему недоступна снаружи — но это уже не важно, потому что мы не пытаемся к ней обращаться.
Шаг 4.
Использовать внешнюю переменную вместо попытки обратиться к локальной:
def calc():
result = 42
return result
value = calc()
print(value) # 42 — работает без ошибок
Ключевая идея: return — это единственный стандартный способ передать данные из тела функции в вызывающий код. Без него значение остаётся заперто внутри. После return функция возвращает объект, и вызов calc() в правой части присваивания вычисляется именно в это значение.
Посмотрим на чуть более реалистичный пример — функцию, которая считает длину строки:
def get_length(text):
length = len(text)
return length
word = "Python"
result = get_length(word)
print(result) # 6
Здесь length — локальная переменная, она исчезает после завершения get_length. Но её значение уже передано наружу через return и живёт в result. Именно этот паттерн — вычислить внутри, вернуть через return, использовать снаружи — является стандартным способом работы с функциями.
Одна деталь, которую легко пропустить: если написать calc() без присваивания, Python всё равно выполнит функцию и получит возвращаемое значение — но сразу же его выбросит, потому что некуда сохранить. Поэтому return без переменная = вызов(...) бесполезен для передачи данных.
