Область видимости переменных и `lambda`-функции - Python с нуля до Junior: Путь к первой работе в IT - Qpel.AI

Область видимости переменных и `lambda`-функции

В прошлом уроке мы научились создавать функции, передавать им данные и получать результат. Теперь давайте разберёмся, как переменные «живут» внутри и вне функций, а ещё познакомимся с компактным способом писать простые функции.

Область видимости переменных (Scope)

Когда вы создаёте переменную, она существует в определённой области видимости. Представьте это как невидимые границы, внутри которых переменная «видна» и доступна. В Python есть несколько таких «границ», но для начала нам хватит двух основных:

  1. Локальная область видимости (Local Scope): Переменные, которые вы создали внутри функции. Они доступны только в этой функции и исчезают, как только функция закончит работу.
  2. Глобальная область видимости (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-функции, вы готовы к следующему шагу: научиться организовывать ваш код в модули и пакеты, чтобы создавать более крупные и управляемые проекты.