Similar presentations:
Декораторы
1. Декораторы
2. Напоминание
• Инкапсуляция: объединение данных и методов, которыеработают с этими данными, в одном классе и скрытие их от
остального кода.
• Наследование: возможность создавать новые классы на основе
уже существующих и наследовать их свойства и методы.
• Полиморфизм: возможность объектов с одинаковым
интерфейсом иметь разные реализации методов.
3.
4. Абстракция и композиция
• Абстракция: создание упрощенной модели объекта, котораяпозволяет сосредоточиться на основных характеристиках
объекта, игнорируя мелкие детали. Абстракция позволяет
разрабатывать более гибкие и масштабируемые программы.
• Композиция: создание нового объекта путем объединения уже
существующих объектов. Композиция позволяет создавать
объекты, которые могут выполнять сложные задачи, используя
функциональность других объектов.
5.
• Aбстракция позволяет:Выделить главные и наиболее значимые свойства предмета.
• Отбросить второстепенные характеристики.
• Когда мы имеем дело с составным объектом - мы прибегаем к
абстракции. Например, мы должны понимать, что перед нами
абстракция, если мы рассматриваем объект как "дом", а не
совокупность кирпича, стекла и бетона. А если уже представить
множество домов как "город", то мы снова приходим к абстракции, но
уже на уровень выше.
Зачем нужна абстракция? Если мыслить масштабно - то она позволяет
бороться со сложностью реального мира. Мы отбрасываем все
лишнее, чтобы оно нам не мешало, и концентрируемся только на
важных чертах объекта.
6. Статические и динамические поля
7. Рекомендации к созданию классов
• Создавайте классы, которые отвечают только за одну задачу, иследуйте принципу единственной ответственности.
• Используйте наследование, чтобы избежать дублирования кода и
упростить его поддержку.
• Используйте полиморфизм, чтобы обеспечить гибкость кода и
упростить его использование.
• Используйте инкапсуляцию, чтобы скрыть детали реализации и
обеспечить безопасность кода.
• Помните, что классы должны моделировать реальные объекты и
процессы, а не только выполнять задачи.
• Документируйте каждый класс и его методы, чтобы облегчить его
использование другими разработчиками.
8.
• Чтобы избежать создания слишком сложных и неструктурированных классов, можноиспользовать следующие советы:
• Разбейте класс на более мелкие подклассы, каждый из которых решает отдельную задачу.
• Используйте наследование, чтобы избежать дублирования кода.
• Избегайте сильной связности между классами, чтобы классы были более переносимыми и
гибкими.
• Не добавляйте в классы функциональность, которая не относится к их основной задаче.
• Избегайте создания слишком многих методов и атрибутов в классе, чтобы класс был проще
в использовании и понимании.
• Используйте исключения, чтобы сообщать об ошибках внутри класса, вместо того, чтобы
просто возвращать ошибочное значение.
• Разделяйте классы на слои, чтобы каждый слой решал свою задачу, и классы внутри слоя
имели схожую функциональность.
9.
• Еще одной особенностью ООП в Python является наличиемагических методов, которые позволяют определять поведение
объектов в различных ситуациях. Например, метод __str__
определяет строковое представление объекта, а метод __len__
определяет длину объекта. Магические методы позволяют
создавать более гибкие и мощные объекты, но их неправильное
использование может привести к сложностям в понимании кода.
10. Статические методы
• Статические методы - это обычные функции, которые помещены вкласс для удобства и тем самым располагаются в области видимости
этого класса. Чаще всего это какой-то вспомогательный код.
Важная особенность заключается в том, что данные методы можно
вызывать посредством обращения к имени класса, создавать объект
класса при этом не обязательно. Именно поэтому в таких методах не
используется self - этому методу не важна информация об объектах
класса.
Чтобы создать статический метод в Python, необходимо
воспользоваться специальным декоратором - @staticmethod.
Выглядит это следующим образом:
11.
• В Python также есть возможность использовать декораторы,которые позволяют модифицировать поведение методов и
классов. Например, декоратор @property позволяет использовать
метод как атрибут, а декоратор @staticmethod позволяет
определить статический метод, который не имеет доступа к
атрибутам и методам объекта.
12.
• Декораторы – это обертка вокруг функций (или классов) в Python,которая меняет способ работы этой функции.
13. Пример
def myfunction():print('hello')
print(type(myfunction))
> <class 'function'>
14.
class myclass:a='hello'
def myfunction():
s= myclass.a
print(s)
print(type(myclass))
> <class 'type'>
15.
• Мы можем сохранять функции в переменные, передавать их вкачестве аргументов и возвращать из других функций. Можно
даже определить одну функцию внутри другой. Иными словами,
функции — это объекты первого класса.
16. Вложенные функции
def wrapperfuntcion():def level1function():
def level2function():
return 'Hello'
return level2function()+' World'
return level1function()+'!'
print(wrapperfuntcion())
17. Пример
def func1(z):z()
def func2():
print('hello')
func1(func2)
18. Пример декоратора
def decorator_function(func):def wrapper():
print('Функция-обёртка!')
print('Оборачиваемая функция: {}'.format(func))
print('Выполняем обёрнутую функцию...')
func()
print('Выходим из обёртки')
return wrapper
19.
• Здесь decorator_function() является функцией-декоратором. Каквы могли заметить, она является функцией высшего порядка, так
как принимает функцию в качестве аргумента, а также
возвращает функцию. Внутри decorator_function() мы определили
другую функцию, обёртку, так сказать, которая обёртывает
функцию-аргумент и затем изменяет её поведение.
20. Декоратор в действии
@decorator_functiondef hello_world():
print('Hello world!')
hello_world()
21.
22.
• Просто добавив @decorator_function перед определениемфункции hello_world(), мы модифицировали её поведение,
выражение с @ является всего лишь синтаксическим сахаром для
hello_world = decorator_function(hello_world).
23.
24. Еще пример
def benchmark(func):import time
def wrapper():
start = time.time()
func()
end = time.time()
print('[*] Время выполнения: {} секунд.'.format(end-start))
return wrapper
@benchmark
def fetch_webpage():
import requests
webpage = requests.get('https://yandex.ru')
fetch_webpage()
25. Аргументы и возвращаемые значения
def benchmark(func):import time
def wrapper(*args, **kwargs):
start = time.time()
return_value = func(*args, **kwargs)
end = time.time()
print('[*] Время выполнения: {} секунд.'.format(end-start))
return return_value
return wrapper
@benchmark
def fetch_webpage(url):
import requests
webpage = requests.get(url)
return webpage.text
webpage = fetch_webpage('https://yandex.ru')
print(webpage)
26.
27.
• Как вы видите, аргументы декорируемой функции передаютсяфункции-обёртке, после чего с ними можно делать что угодно.
Можно изменять аргументы и затем передавать их декорируемой
функции, а можно оставить их как есть или вовсе забыть про них
и передать что-нибудь совсем другое. То же касается
возвращаемого из декорируемой функции значения, с ним тоже
можно делать что угодно.
28. Декораторы с аргументами
def benchmark(iters):def actual_decorator(func):
import time
def wrapper(*args, **kwargs):
total = 0
for i in range(iters):
start = time.time()
return_value = func(*args, **kwargs)
end = time.time()
total = total + (end-start)
print('[*] Среднее время выполнения: {} секунд.'.format(total/iters))
return return_value
return wrapper
return actual_decorator
@benchmark(iters=3)
def fetch_webpage(url):
import requests
webpage = requests.get(url)
return webpage.text
webpage = fetch_webpage('https://google.com')
29.
• Здесь мы модифицировали наш старый декоратор таким образом,чтобы он выполнял декорируемую функцию iters раз, а затем выводил
среднее время выполнения. Однако чтобы добиться этого, пришлось
воспользоваться природой функций в Python.
• Функция benchmark() на первый взгляд может показаться
декоратором, но на самом деле таковым не является. Это обычная
функция, которая принимает аргумент iters, а затем возвращает
декоратор. В свою очередь, он декорирует функцию fetch_webpage().
Поэтому мы использовали не выражение @benchmark, а
@benchmark(iters=3) — это означает, что тут вызывается функция
benchmark() (функция со скобками после неё обозначает вызов
функции), после чего она возвращает сам декоратор.
30.
def decorator(func):'''Основная функция'''
print('1. Декоратор')
def wrapper():
print('3. до функции', func.__name__)
func()
print('5. после функции', func.__name__)
return wrapper
print('0. Начало')
@decorator
def wrapped():
print('4. Обернутая функция')
print('2. старт программы...')
wrapped()
print('- конец программы')
31. Декоратор-класс
class myclassdecorator:def __init__(self, func):
print('Класс Decorator метод __init__')
self.func = func
def __call__(self):
print('перед вызовом класса...', self.func.__name__)
self.func()
print('после вызова класса')
@myclassdecorator
def wrapped():
print('функция wrapped')
print('старт')
wrapped()
print('конец')
32.
• Отличие в том, что класс инициализируется при объявлении. Ондолжен получить функцию в качестве аргумента для метода
__init__. Это и будет декорируемая функция.
• При вызове декорируемой функции на самом деле вызывается
экземпляр класса. А поскольку объект вызываемый, то
вызывается функция __call__.
33. Документация
• Один из атрибутов функции — строка документации (docstring),доступ к которой можно получить с помощью __doc__. Это
строковая константа, определяемая как первая инструкция в
объявлении функции.
34. Встроенные декораторы
• Python содержит несколько встроенных декораторов. Из всехэтих декораторов, самой важной троицей являются:
• @classmethod
• @staticmethod
• @property
• Также существуют декораторы в различных разделах стандартной
библиотеки Python. Одним из примеров является functools.wraps.
Мы сосредоточимся на трех главных декораторах, указанных
выше.
35. @classmethod и @staticmethod
• Декоратор <*@classmethod>* может быть вызван при помощи экземпляракласса, или напрямую, через собственный класс Python в качестве первого
аргумента. В соответствии с документацией Python: он может быть вызван
как в классе (например, C.f()), или в экземпляре (например, C().f()).
Экземпляр игнорируется, за исключением его класса. Если метод класса
вызван для выведенного класса, то объект выведенного класса
передается в качестве подразумеваемого первого аргумента.
• Декоратор @classmethod, в первую очередь, используется как чередуемый
конструктор или вспомогательный метод для инициализации.
• Декоратор <*@staticmethod>* — это просто функция внутри класса. Вы
можете вызывать их обоих как с инициализацией класса так и без создания
экземпляра класса. Обычно это применяется в тех случаях, когда у вас есть
функция, которая, по вашему убеждению, имеет связь с классом. По
большей части, это выбор стиля.
36.
37. Декоратор @property
class Rectangle:def __init__(self, a, b):
self.a = a
self.b = b
@property
def area(self):
return self.a * self.b
rect = Rectangle(5, 6)
print(rect.area)
38.
• Один из самых простых способов использования property, этоиспользовать его в качестве декоратора метода. Это позволит
вам превратить метод класса в атрибут класса. Для меня это было
очень полезно, когда мне нужно сделать какую-нибудь
комбинацию значений.
programming