Функции

Для объявления функций используется ключевое слово def, для возврата значения используется return:


def double(x):
    return x * 2

Для вызова функции использутся её имя и скобки:


print(double(5))  # 10

Имя функции без скобок дает ссылку на функцию:


print(double)  # <function double at 0x7f88d9ef94c0>

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

Ключевое слово pass позволяет создать пустой блок операторов. То есть, такая функция синтаксически верна, но ничего не делает:


def empty():
    pass

Don’t Repeat Yourself — DRY

Важнейшее свойство качественного кода — отсутствие повторяющихся фрагментов.

Все повторяющие фрагменты следует заключать в функции или циклы.

Активное использование функций позволяет:

  • разделить код на структурные элементы
  • улучшить читабельность и понятность кода
  • повторно использовать однажды написанный код
  • уменьшить количество ошибок

Значение аргументов по умолчанию

Для аргументов функции можно задать значение по умолчанию:


def summa(x, y=1):
    return x + y

summa(2, 3)  # Ответ 5
summa(7)  # Ответ 8

Передача аргументов по имени

При вызове функции можно передать аргументы по имени:


def greeting(name, surname):
    print("Hello", name, surname)

greeting("Иван", "Сидоров")  # Hello Иван Сидоров
greeting(surname="Сидоров", name="Иван")  # Hello Иван Сидоров

Обработка произвольного количества аргументов

Функция может получить произвольное количество аргументов в виде кортежа:


def func(*args):
    s = 0
    for i in args:
        s += i
    return s

print(func(1, 2))  # 3
print(func(3, 4, 5, 6))  # 18

В момент вызова функции можно передать ей коллекцию аргументов произвольной длины:


arguments = [7, 8, 9]
print(func(*arguments))  # 24

Функция может получить произвольное количество именованных аргументов в виде словаря:


def func(**kwargs):
    for k, v in kwargs.items():
        print(k, v)

func(a=1, b=2, c=3)

В функцию можно передать словарь именованных аргументов:


keyword_arguments = dict(zip('ABCDE', range(1, 6)))
func(**keyword_arguments)

Функция может получить произвольное количество аргументов в виде кортежа и произвольное количество аргументов по имени в виде словаря:


def func(*args, **kwargs):
    s = 0
    for a in args:
        s += a

    for a in kwargs.values():
        s += a

    return s

func(1, 2, 3, a=4, b=5, c=6)

arguments = [7, 8, 9]
keyword_arguments = dict(a=4, b=5, c=6)
func(*arguments, **keyword_arguments)

Если функция сочетает обработку произвольного количества позиционных и именованных аргументов, то все именованные аргументы должны быть указаны после позиционных.

Понятие контекста выполнения

Контекст выполнения — это пространство (множество) имен в которое входят:

  • имена переменных
  • имена функций
  • имена классов
  • имена импортированные из модулей и пакетов

В Python различают два вида контекстов:

  • Глобальный контекст выполнения (global scope). Код записанный за пределами классов и функций выполняется в глобальном контексте. Глобальный контекст создается при запуске интерпретатора Python. Текущее состояние глобального контекста можно увидеть с помощью функции globals().
  • Локальный контекст выполнения (local scopes). Код функций выполняется в локальном контексте. Каждый раз когда вызывается функция в памяти интерпретатора создается новый локальный контекст. Текущее состояние локального контекста можно увидеть с помощью функции locals(). Однако, если вызвать функцию locals() за пределами функций, то мы получим глобальный контекст.

Когда в коде происходит обращение к имени (переменной, функции, класса), то сначала просматривается локальный контекст. Если подходящее значение не найдено тогда последовательно просматриваются локальные контексты внешних функций (если код выполняется во вложенной функции) и глобальный контекст.

Для более точного указания контекста к которому принадлежит имя (переменной, функции или класса) служат два ключевых слова:

  • global — используется если имя объявлено в глобальном контексте.
  • nonlocal — используется если что имя объявлено в локальном контексте внешней функции.