Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Топ:
Оценка эффективности инструментов коммуникационной политики: Внешние коммуникации - обмен информацией между организацией и её внешней средой...
Методика измерений сопротивления растеканию тока анодного заземления: Анодный заземлитель (анод) – проводник, погруженный в электролитическую среду (грунт, раствор электролита) и подключенный к положительному...
Особенности труда и отдыха в условиях низких температур: К работам при низких температурах на открытом воздухе и в не отапливаемых помещениях допускаются лица не моложе 18 лет, прошедшие...
Интересное:
Как мы говорим и как мы слушаем: общение можно сравнить с огромным зонтиком, под которым скрыто все...
Инженерная защита территорий, зданий и сооружений от опасных геологических процессов: Изучение оползневых явлений, оценка устойчивости склонов и проектирование противооползневых сооружений — актуальнейшие задачи, стоящие перед отечественными...
Что нужно делать при лейкемии: Прежде всего, необходимо выяснить, не страдаете ли вы каким-либо душевным недугом...
Дисциплины:
2023-02-03 | 25 |
5.00
из
|
Заказать работу |
|
|
>>> # Теперь наконец вызовем функцию:
>>> decorated_function()
Я - обёртка вокруг декорируемой функции.
Я буду вызвана каждый раз, когда ты вызываешь декорируемую функцию.
Я возвращаю результат работы декорируемой функции.
Я - декорируемая функция.
Теперь перепишем данный код с помощью декораторов:
>>>
>>> @decorator_maker ()
... def decorated_function():
... print("Я - декорируемая функция.")
...
Я создаю декораторы! Я буду вызван только раз: когда ты попросишь меня создать декоратор.
Я возвращаю декоратор.
Я - декоратор! Я буду вызван только раз: в момент декорирования функции.
Я возвращаю обёрнутую функцию.
>>> decorated_function()
Я - обёртка вокруг декорируемой функции.
Я буду вызвана каждый раз когда ты вызываешь декорируемую функцию.
Я возвращаю результат работы декорируемой функции.
Я - декорируемая функция.
Вернёмся к аргументам декораторов, ведь, если мы используем функцию, чтобы создавать декораторы "на лету", мы можем передавать ей любые аргументы, верно?
>>>
>>>def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
... print("Я создаю декораторы! И я получил следующие аргументы:",
... decorator_arg1, decorator_arg2)
... def my_decorator(func):
... print("Я - декоратор. И ты всё же смог передать мне эти аргументы:",
... decorator_arg1, decorator_arg2)
... # Не перепутайте аргументы декораторов с аргументами функций!
... def wrapped(function_arg1, function_arg2):
... print ("Я - обёртка вокруг декорируемой функции.\n"
... "И я имею доступ ко всем аргументам\n"
... "\t- и декоратора: {0}{1}\n"
... "\t- и функции: {2}{3}\n"
... "Теперь я могу передать нужные аргументы дальше"
|
... .format(decorator_arg1, decorator_arg2,
... function_arg1, function_arg2))
... return func(function_arg1, function_arg2)
Return wrapped
... return my_decorator
...
>>> @decorator_maker_with_arguments ("Леонард", "Шелдон")
... def decorated_function_with_arguments(function_arg1, function_arg2):
... print ("Я - декорируемая функция и я знаю только о своих аргументах: {0}"
... " {1}".format(function_arg1, function_arg2))
...
Я создаю декораторы! И я получил следующие аргументы: Леонард Шелдон
Я - декоратор. И ты всё же смог передать мне эти аргументы: Леонард Шелдон
>>> decorated_function_with_arguments(" Раджеш ", " Говард ")
Я - обёртка вокруг декорируемой функции.
И я имею доступ ко всем аргументам
- и декоратора: Леонард Шелдон
- и функции: РаджешГовард
Теперь я могу передать нужные аргументы дальше
Я - декорируемая функция и я знаю только о своих аргументах: РаджешГовард
Таким образом, мы можем передавать декоратору любые аргументы, как обычной функции. Мы можем использовать и распаковку через *args и **kwargs в случае необходимости.
Некоторые особенности работы с декораторами
· Декораторы несколько замедляют вызов функции, не забывайте об этом.
· Вы не можете "раздекорировать" функцию. Безусловно, существуют трюки, позволяющие создать декоратор, который можно отсоединить от функции, но это плохая практика. Правильнее будет запомнить, что если функция декорирована — это не отменить.
· Декораторы оборачивают функции, что может затруднить отладку.
Последняя проблема частично решена добавлением в модуле functools функции functools.wraps, копирующей всю информацию об оборачиваемой функции (её имя, из какого она модуля, её документацию и т.п.) в функцию-обёртку.
Забавным фактом является то, что functools.wraps тоже является декоратором.
>>>
>>>def foo():
... print("foo")
...
>>> print(foo.__name__)
Foo
>>> # Однако, декораторы мешают нормальному ходу дел:
|
... def bar(func):
... def wrapper():
... print("bar")
Return func()
Return wrapper
...
>>> @bar
... def foo():
... print("foo")
...
>>> print(foo.__name__)
Wrapper
>>> importfunctools # "functools" можетнамсэтимпомочь
>>>def bar(func):
... # Объявляем "wrapper" оборачивающим "func"
... # и запускаем магию:
... @functools .wraps(func)
... def wrapper():
... print("bar")
Return func()
Return wrapper
...
>>> @bar
... def foo():
... print("foo")
...
>>> print(foo.__name__)
Foo
Примеры использования декораторов
Декораторы могут быть использованы для расширения возможностей функций из сторонних библиотек (код которых мы не можем изменять), или для упрощения отладки (мы не хотим изменять код, который ещё не устоялся).
Также полезно использовать декораторы для расширения различных функций одним и тем же кодом, без повторного его переписывания каждый раз, например:
>>>
>>>def benchmark(func):
... """
... Декоратор, выводящий время, которое заняло
... выполнение декорируемой функции.
... """
Importtime
... def wrapper(*args, **kwargs):
... t = time.clock()
... res = func(*args, **kwargs)
... print(func.__name__, time.clock() - t)
Return res
Return wrapper
...
>>>def logging(func):
... """
... Декоратор, логирующий работу кода.
... (хорошо, он просто выводит вызовы, но тут могло быть и логирование!)
... """
... def wrapper(*args, **kwargs):
... res = func(*args, **kwargs)
... print(func.__name__, args, kwargs)
Return res
Return wrapper
...
>>>def counter(func):
... """
... Декоратор, считающий и выводящий количество вызовов
... декорируемой функции.
... """
... def wrapper(*args, **kwargs):
... wrapper.count += 1
... res = func(*args, **kwargs)
... print("{0} былавызвана : {1}x".format(func.__name__, wrapper.count))
Return res
... wrapper.count = 0
Return wrapper
...
>>> @benchmark
... @logging
... @counter
... def reverse_string(string):
|
|
Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...
Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!