📖 Теория

⚡ Кратко: теория

Функция - именованный блок кода, который можно вызывать много раз.

def создаёт функцию, pass временно оставляет обязательный блок пустым.

При вызове функции позиционные аргументы сопоставляются по порядку, именованные - по названию параметра.

Аргументы по умолчанию пишутся после обязательных параметров.

*args собирает лишние позиционные аргументы в tuple, **kwargs - именованные аргументы в dict.

return завершает функцию и возвращает значение; без return результатом будет None.

LEGB описывает поиск имён: Local, Enclosing, Global, Built-in.

global нужен только для изменения глобальной переменной, но чаще лучше передавать данные параметрами.

Топ-3 ошибки: передавать не то количество аргументов; ожидать значение от функции, где нет return; менять global там, где достаточно параметров и return.

Функция как именованный блок

Функция нужна, чтобы выделить повторяемую операцию в самостоятельный блок с понятным именем.

Хорошее имя функции обычно начинается с глагола и отвечает на вопрос, что делает код.

def greet(name):
    return f"Hello, {name}!"

print(greet("Alice"))

pass и def

pass ничего не выполняет, но позволяет оставить синтаксически корректный блок.

Это полезно для заготовок, когда интерфейс функции уже понятен, а реализация появится позже.

def validate_data():
    pass

print(validate_data())

Аргументы функций

Позиционные аргументы зависят от порядка. Именованные аргументы делают вызов читаемее и могут идти в другом порядке.

Default-аргументы задают значение на случай, если вызывающий код его не передал.

def greet(name, age, greeting="Hello"):
    return f"{greeting}, {name}! Age: {age}"

print(greet("Bob", 30))
print(greet(age=25, name="Alice", greeting="Hi"))

*args и **kwargs

*args собирает произвольное количество позиционных значений, а **kwargs - произвольное количество именованных значений.

Порядок параметров: обычные параметры, *args, параметры со значениями по умолчанию, **kwargs.

def show_full_info(name, *details, age=25, **extra):
    return name, details, age, extra

print(show_full_info("Alice", "Developer", age=30, city="New York"))

return и None

return возвращает результат в место вызова и сразу завершает функцию.

Если return отсутствует или написан без значения, функция возвращает None.

def check_positive(number):
    if number > 0:
        return "Positive"
    return "Non-positive"

print(check_positive(-1))

LEGB и global

Python ищет имя в Local, затем Enclosing, затем Global, затем Built-in.

global разрешает изменить глобальное имя внутри функции, но такая зависимость ухудшает тестируемость.

counter = 0

def increment_counter():
    global counter
    counter += 1

increment_counter()
print(counter)
Проверить по документации: современные детали поведения встроенных функций, стандартной библиотеки и версии Python сверяйте с официальной документацией.