>>>> cooler_add_ints(3, 5)
>Running function: add_ints
>Positional arguments: (3, 5)
>Keyword arguments: {}
>Result: 8
>8
В качестве альтернативы мануальному присваиванию декоратора, показанному выше, просто добавьте конструкцию @имя_декоратора перед функцией, которую хотите декорировать:
>>>> @document_it
>… def add_ints(a, b):
>…·····return a + b
>…
>>>> add_ints(3, 5)
>Start function add_ints
>Positional arguments: (3, 5)
>Keyword arguments: {}
>Result: 8
>8
Каждая функция может иметь более одного декоратора. Напишем еще один декоратор, который называется square_it() и возводит результат в квадрат.
>>>> def square_it(func):
>…·····def new_function(*args, **kwargs):
>…·········result = func(*args, **kwargs)
>…·········return result * result
>…·····return new_function
>…
Декоратор, размещенный ближе всего к функции (прямо над def), будет выполнен первым, а затем — тот, что находится сразу над ним. Любой порядок вызова вернет один и тот же конечный результат, но вы можете увидеть, как меняются промежуточные шаги:
>>>> @document_it
>… @square_it
>… def add_ints(a, b):
>…·····return a + b
>…
>>>> add_ints(3, 5)
>Running function: new_function
>Positional arguments: (3, 5)
>Keyword arguments: {}
>Result: 64
>64
Попробуем поменять порядок декораторов:
>>>> @square_it
>… @document_it
>… def add_ints(a, b):
>…·····return a + b
>…
>>>> add_ints(3, 5)
>Running function: add_ints
>Positional arguments: (3, 5)
>Keyword arguments: {}
>Result: 8
>64
Пространства имен и область определения
Имя может ссылаться на несколько разных вещей в зависимости от того, где оно используется. Программы в Python могут иметь разные пространства имен — разделы, внутри которых определенное имя уникально и не связано с такими же именами в других пространствах имен.
Каждая функция определяет собственное пространство имен. Если вы определите переменную, которая называется х в основной программе, и другую переменную х в отдельной функции, они будут ссылаться на разные значения. Но эту стену можно пробить: если нужно, вы можете получить доступ к именам других пространств имен разными способами.
В основной программе определяется глобальное пространство имен, поэтому переменные, находящиеся в этом пространстве имен, являются глобальными.
Вы можете получить значение глобальной переменной внутри функции:
>>>> animal = 'fruitbat'
>>>> def print_global():
>…·····print('inside print_global:', animal)
>…
>>>> print('at the top level:', animal)
>at the top level: fruitbat
>>>> print_global()
>inside print_global: fruitbat
Но если попробуете получить значение глобальной переменной и изменить его внутри функции, получите ошибку: