Область видимости переменных и `lambda`-функции
В прошлом уроке мы научились создавать функции, передавать им данные и получать результат. Теперь давайте разберёмся, как переменные «живут» внутри и вне функций, а ещё познакомимся с компактным способом писать простые функции.
Область видимости переменных (Scope)
Когда вы создаёте переменную, она существует в определённой области видимости. Представьте это как невидимые границы, внутри которых переменная «видна» и доступна. В Python есть несколько таких «границ», но для начала нам хватит двух основных:
- Локальная область видимости (Local Scope): Переменные, которые вы создали внутри функции. Они доступны только в этой функции и исчезают, как только функция закончит работу.
- Глобальная область видимости (Global Scope): Переменные, созданные вне всех функций, прямо в основном коде. Они доступны из любой части программы, включая функции.
Посмотрим на примере:
# Это глобальная переменная
global_message = "Привет из глобальной области!"
def greet():
# Это локальная переменная
local_name = "Алиса"
print(f"{global_message} {local_name}!")
def another_function():
# Попытка использовать local_name здесь вызовет ошибку,
# потому что она локальна только для функции greet()
# print(local_name) # Это вызовет NameError
# А вот к глобальной переменной доступ есть
print(global_message)
greet()
another_function()
# И здесь local_name тоже недоступна, будет ошибка
# print(local_name) # NameError
Важно: Старайтесь не менять глобальные переменные внутри функций. Это делает код запутанным и сложным для поиска ошибок. Лучше передавайте данные в функцию через параметры, а результат возвращайте с помощью
return.
Ключевое слово global
Иногда всё же нужно изменить глобальную переменную изнутри функции. Для этого используйте ключевое слово global.
counter = 0 # Глобальная переменная
def increment_counter():
global counter # Объявляем: будем работать с глобальной переменной counter
counter += 1
print(f"Счётчик внутри функции: {counter}")
print(f"Счётчик до вызова функции: {counter}")
increment_counter()
increment_counter()
print(f"Счётчик после вызова функции: {counter}")
Совет: Используйте
globalочень осторожно. Если злоупотреблять им, код превратится в «спагетти», где невозможно понять, откуда и как меняются данные. В большинстве случаев лучше передавать переменные как аргументы или возвращать их из функций.
lambda-функции: Компактные функции без имени
Python позволяет создавать маленькие, однострочные функции без имени. Их называют lambda-функциями (или анонимными функциями). Они очень удобны, когда вам нужна простая функция для одной конкретной задачи, и вы не планируете использовать её где-то ещё.
Синтаксис lambda-функции:
lambda аргументы: выражение
lambda– это ключевое слово.аргументы– список аргументов, как у обычных функций, через запятую.выражение– это то, что делает функция. Результат этого выражения будет возвращён.
Пример:
# Обычная функция для сложения
def add_numbers(x, y):
return x + y
print(add_numbers(5, 3)) # Вывод: 8
# Эквивалентная lambda-функция
add_lambda = lambda x, y: x + y
print(add_lambda(5, 3)) # Вывод: 8
# Lambda-функция без аргументов
say_hello = lambda: "Привет, мир!"
print(say_hello()) # Вывод: Привет, мир!
# Lambda-функция с одним аргументом
square = lambda x: x * x
print(square(7)) # Вывод: 49
Когда использовать lambda-функции?
lambda-функции часто применяют вместе с функциями, которые принимают другие функции как аргументы. Например, с map(), filter() и sorted().
# Пример с sorted()
students = [
{'name': 'Иван', 'grade': 95},
{'name': 'Мария', 'grade': 88},
{'name': 'Петр', 'grade': 92}
]
# Сортируем список студентов по оценке (grade)
sorted_students = sorted(students, key=lambda student: student['grade'])
print(sorted_students)
# Вывод: [{'name': 'Мария', 'grade': 88}, {'name': 'Петр', 'grade': 92}, {'name': 'Иван', 'grade': 95}]
# Пример с filter()
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Отфильтровываем только чётные числа
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Вывод: [2, 4, 6, 8, 10]
# Пример с map()
numbers_to_square = [1, 2, 3, 4, 5]
# Возводим каждое число в квадрат
squared_numbers = list(map(lambda x: x * x, numbers_to_square))
print(squared_numbers) # Вывод: [1, 4, 9, 16, 25]
lambda-функции делают код короче и понятнее, когда речь идёт о простых действиях. Но для сложной логики всегда используйте обычные функции def.
Теперь, когда вы разобрались с областями видимости и научились создавать компактные lambda-функции, вы готовы к следующему шагу: научиться организовывать ваш код в модули и пакеты, чтобы создавать более крупные и управляемые проекты.