Локальные переменные в Python: что нужно знать каждому разработчику
Определение и создание локальных переменных
Как объявить переменную, которая существует только внутри функции?
Локальная переменная создаётся при первом присваивании внутри функции. Она доступна только в пределах этой функции и уничтожается после её завершения. Пример:
def my_func():
local_var = 10
print(local_var)
my_func() # Вывод: 10
# print(local_var) # NameError: name 'local_var' is not definedPython arguments types (типы аргументов в python)
Важно:
Если переменная с таким же именем существует глобально, внутри функции будет создана новая локальная, не связанная с глобальной.
Частая ошибка: попытка обратиться к локальной переменной вне функции приводит к NameError. Решение: вынести значение через return.
Как сделать переменную доступной для всех вложенных функций?
Используется ключевое слово nonlocal для доступа к переменной из внешней (не глобальной) области видимости.
def outer():
x = 5
def inner():
nonlocal x
x += 1
inner()
print(x) # 6
outer()Python load module (загрузка модуля в python)
Проблема: без nonlocal будет создана новая локальная переменная x внутри inner, а внешняя останется без изменений.
Как изменить глобальную переменную внутри функции?
Объявить переменную как global:
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # 1
Pd pandas python (импорт пакетов python)
Без global присваивание создаст локальную переменную counter, что приводит к UnboundLocalError при попытке использования до присваивания.
Как избежать конфликта имён локальных и глобальных переменных?
Рекомендуется не использовать одинаковые имена для локальных и глобальных переменных. Если конфликт неизбежен, явно указывать global или nonlocal.
value = 100
def func(value): # параметр тоже локальная переменная
print(value) # 50
func(50)
print(value) # 100 (глобальная не изменилась)How to use python (как использовать python)
Параметр функции является локальной переменной, даже если имя совпадает с глобальной. Изменение параметра не затрагивает глобальную.
Какие особенности области видимости в циклах и условных конструкциях?
В Python 3 переменные, созданные внутри блоков if, for, while, не имеют собственной области видимости. Они становятся локальными для функции (или глобальными, если код вне функций).
def loop_example():
for i in range(3):
temp = i * 2
print(temp) # 4, переменная temp доступна после цикла
loop_example()как писать код на python (как писать код на python)
Это может привести к неожиданному использованию переменной вне цикла.
Ошибка: случайное использование переменной, которая была создана внутри цикла, за пределами цикла. Решение: явно инициализировать переменную до цикла, если она нужна после.
Как работают локальные переменные в лямбда-выражениях?
Лямбда-функции захватывают переменные из внешней области видимости по ссылке, но значение вычисляется при вызове лямбды.
funcs = []
for x in range(3):
funcs.append(lambda: x * 2)
print([f() for f in funcs]) # [4, 4, 4] (все равны последнему x=2)Python log 2 (логарифм по основанию 2 в python)
Проблема: все лямбды ссылаются на одну и ту же переменную x, которая к моменту вызова равна 2. Решение: lambda x=x: x*2 - передать значение как аргумент по умолчанию.
Как создаются замыкания с локальными переменными?
Если вложенная функция использует переменные внешней функции, они сохраняются даже после завершения внешней функции. Это называется замыканием.
def make_multiplier(n):
def multiplier(x):
return x * n
return multiplier
times3 = make_multiplier(3)
print(times3(5)) # 15Локальная переменная n сохраняется в замыкании.
Расширенные примеры работы с локальными переменными
1. Влияние порядка присваивания на область видимости
def test():
print(x) # NameError?
x = 10
test()UnboundLocalError: local variable 'x' referenced before assignment
Ошибка возникает из-за того, что интерпретатор видит присваивание x = 10 и считает x локальной переменной, но пытается прочитать её до инициализации.
2. Использование locals() для просмотра локальных переменных
def show_locals(a, b):
c = a + b
print(locals())
show_locals(2, 3){'a': 2, 'b': 3, 'c': 5}Функция locals() возвращает словарь всех локальных переменных в текущей области видимости. Это удобно для отладки.
3. Вложенные функции и nonlocal без присваивания
def outer():
x = 1
def inner():
print(x) # можно читать без nonlocal
inner()
outer() # 1Для чтения внешней переменной внутри вложенной функции nonlocal не требуется. Он нужен только для присваивания.
4. Локальные переменные в декораторах
def decorator(func):
count = 0
def wrapper(*args, **kwargs):
nonlocal count
count += 1
print(f'Вызов {count}')
return func(*args, **kwargs)
return wrapper
@decorator
def say_hello():
print('Привет')
say_hello()
say_hello()Вызов 1
Привет
Вызов 2
Привет
Локальная переменная count в декораторе сохраняется между вызовами благодаря замыканию.
5. Переменные в списковых включениях (list comprehensions)
В Python 3 переменная цикла в списковом включении остаётся локальной для функции (или глобальной, если вне функций). Это может быть неочевидно.
def comp_example():
squares = [x*x for x in range(5)]
print(x) # 4?
comp_example()4
Переменная x доступна и после завершения включения. В Python 2 она была локальной только внутри включения, что приводило к утечке.
6. Глобальные и локальные переменные в модулях: импорт
# module.py
global_var = 'global'
# main.py
import module
module.global_var = 'changed'
# Локальная переменная в main не влияет на moduleКаждый модуль имеет свою глобальную область видимости. Локальные переменные функции принадлежат только этой функции.