Содержание
- 2. функции в python являются объектами их можно возвращать из другой функции или передавать в качестве аргумента.
- 3. Декораторы — это "обёртки", которые дают нам возможность изменить поведение функции, не изменяя её код.
- 4. Создадим свой декоратор "вручную":
- 5. >>> def my_shiny_new_decorator(function_to_decorate): ... # Внутри себя декоратор определяет функцию-"обёртку". Она будет обёрнута вокруг декорируемой, ...
- 6. ... def the_wrapper_around_the_original_function(): ... print("Я - код, который отработает до вызова функции") ... function_to_decorate() # Сама
- 7. ... # Вернём эту функцию ... return the_wrapper_around_the_original_function ... >>> # Представим теперь, что у нас
- 8. >>> def stand_alone_function(): ... print("Я простая одинокая функция, ты ведь не посмеешь меня изменять?")
- 9. >>> # Однако, чтобы изменить её поведение, мы можем декорировать её, то есть просто передать декоратору,
- 10. >>> stand_alone_function_decorated = my_shiny_new_decorator(stand_alone_function) >>> stand_alone_function_decorated() Я - код, который отработает до вызова функции Я простая
- 11. мы бы хотели, чтобы каждый раз, во время вызова stand_alone_function, вместо неё вызывалась stand_alone_function_decorated. Для этого
- 12. >>>>>> stand_alone_function = my_shiny_new_decorator(stand_alone_function) >>> stand_alone_function() Я - код, который отработает до вызова функции Я простая
- 13. это и есть декораторы Вот так можно было записать предыдущий пример, используя синтаксис декораторов:
- 14. >>> @my_shiny_new_decorator ... def another_stand_alone_function(): ... print("Оставь меня в покое") ... >>> another_stand_alone_function() Я - код,
- 15. декораторы в python — это просто синтаксический сахар для конструкций вида: another_stand_alone_function = my_shiny_new_decorator(another_stand_alone_function)
- 16. При этом, естественно, можно использовать несколько декораторов для одной функции, например так:
- 17. >>> def bread(func): ... def wrapper(): ... print() ... func() ... print(" ") ... return wrapper
- 18. def ingredients(func): ... def wrapper(): ... print("#помидоры#") ... func() ... print("~салат~« ) ... return wrapper ...
- 19. def sandwich(food="--ветчина--"): >>> sandwich() --ветчина– >>> sandwich = bread(ingredients(sandwich)) >>> sandwich() #помидоры # --ветчина-- ~салат~
- 20. используя синтаксис декораторов: >>> >>> @bread ... @ingredients ... def sandwich(food="--ветчина--"): ... print(food) ... >>> sandwich()
- 21. нужно помнить о том, что важен порядок декорирования.
- 22. Сравните с предыдущим примером: >>> >>> @ingredients ... @bread ... def sandwich(food="--ветчина--"): ... print(food) ... >>>
- 23. Передача декоратором аргументов в функцию все декораторы, которые мы рассматривали, не имели одного очень важного функционала
- 24. >>>>>> def a_decorator_passing_arguments(function_to_decorate): ... def a_wrapper_accepting_arguments(arg1, arg2): ... print("Смотри, что я получил:", arg1, arg2) ... function_to_decorate(arg1,
- 25. ... >>> # Теперь, когда мы вызываем функцию, которую возвращает декоратор, мы вызываем её "обёртку", >>>
- 26. >>> @a_decorator_passing_arguments ... def print_full_name(first_name, last_name): ... print("Меня зовут", first_name, last_name) ... >>> print_full_name("Vasya", "Pupkin«)
- 27. Смотрите, что я получил: Vasya Pupkin Меня зовут Vasya Pupkin
- 28. ... print(food) ... >>> sandwich() --ветчина-- >>> sandwich = bread(ingredients(sandwich)) >>> sandwich() #помидоры# --ветчина-- ~салат~
- 29. Примеры использования декораторов Декораторы могут быть использованы для расширения возможностей функций из сторонних библиотек (код которых
- 30. Также полезно использовать декораторы для расширения различных функций одним и тем же кодом, без повторного его
- 31. >>> >>> def benchmark(func): ... """ ... Декоратор, выводящий время, которое заняло ... выполнение декорируемой функции.
- 32. ... import time ... def wrapper(*args, **kwargs): ... t = time.clock() ... res = func(*args, **kwargs)
- 33. >>> def logging(func): ... """ ... Декоратор, логирующий работу кода. ... (хорошо, он просто выводит вызовы,
- 34. ... def wrapper(*args, **kwargs): ... res = func(*args, **kwargs) ... print(func.__name__, args, kwargs) ... return res
- 35. ... >>> def counter(func): ... """ ... Декоратор, считающий и выводящий количество вызовов ... декорируемой функции.
- 36. ... def wrapper(*args, **kwargs): ... wrapper.count += 1 ... res = func(*args, **kwargs)
- 37. ... print("{0} была вызвана: {1}x".format(func.__name__, wrapper.count)) ... return res ... wrapper.count = 0 ... return wrapper
- 38. >>> @benchmark ... @logging ... @counter ... def reverse_string(string): ... return ''.join(reversed(string))
- 39. ... >>> print(reverse_string("А роза упала на лапу Азора")) reverse_string была вызвана: 1x wrapper ('А роза упала
- 40. >>> print(reverse_string("A man, a plan, a canoe, pasta, heros, rajahs, a coloratura," ... "maps, snipe, percale,
- 41. ," ... "a jar, sore hats, a peon, a canal: Panama!")) reverse_string была вызвана: 2x wrapper
- 42. ИСПОЛЬЗОВАНИЕ Декораторы сильно облегчают жизнь квалифицированному программисту Резко сокращая необходимый объем требуемой работы и Уменьшая число
- 43. СПАСОБО ЗА ВНИМАНИЕ
- 45. Скачать презентацию