#ООП
Введение
Сегодня мы поговорим о первой из четырёх парадигм ООП, наследовании.
Рассмотрим каким оно должно было быть и какое мы получили в большинстве сегодняшних
языках программирования.
Наследование
Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью.
Класс, от которого производится наследование, называется базовым, родительским или суперклассом.
Новый класс – потомком, наследником или производным классом.
Для того чтобы понять как работает наследование, нам нужно перенестись в реальный мир.
Представим вы повар-технолог в пиццерии, в вашей пиццерии готовят вкусную сырную пиццу.
Но времена меняются и сырная пицца всем приелась, тогда вам поручили задание создать новый вид пиццы.
Очевидно, что вы не будете с нуля создавать новую рецептуру пиццы, вы возьмёте старую сырную пиццу и добавите в неё томатов.
Только что вы применили наследование.
Каким должно было быть наследование?
Помните Айвена Сазерленда? Да-да, того самого, который создал приложение Sketchpad и использовал в нём первый известный объект.
Объекты представляли собой графические знаки, выводимые на экране осциллографа, и поддерживающие наследование через динамических делегатов,
которые он назвал в своей работе «мастер-объектами» (masters).
Любой объект мог стать мастер-объектом, дополнительные экземпляры объекта были названы «реализациями» (occurrences).
Да, именно наследование, правда тогда это было правильное(Именно такое наследование хотел видеть Алан Кей) наследование, которое называется прототипное наследование.
Прототипное наследование vs Классическое наследование(наследование которое мы имеем)
В классическом наследовании экземпляры наследуются от класса, и создают отношения между подклассами.
Другими словами, вы не можете использовать класс, также как вы использовали бы экземпляр.
В прототипном наследовании экземпляры наследуются от других экземпляров.
Используя прототипное наследование, вы просто копируете свойства из объекта в новый экземпляр.
У обоих подходов есть свои плюсы и минусы. Но самым главным различием между ними(кроме того что это два координально разных подхода) является, то
что при использовании прототипного наследования, не обязательно создавать иерархии классов, как побочный эффект при создании подклассов.
Дополнительные материалы
https://bit.ly/3Pobuv7
https://habr.com/ru/company/hexlet/blog/303754/
https://bit.ly/3NepPZ8
Введение
Сегодня мы поговорим о первой из четырёх парадигм ООП, наследовании.
Рассмотрим каким оно должно было быть и какое мы получили в большинстве сегодняшних
языках программирования.
Наследование
Наследование – это свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью.
Класс, от которого производится наследование, называется базовым, родительским или суперклассом.
Новый класс – потомком, наследником или производным классом.
Для того чтобы понять как работает наследование, нам нужно перенестись в реальный мир.
Представим вы повар-технолог в пиццерии, в вашей пиццерии готовят вкусную сырную пиццу.
Но времена меняются и сырная пицца всем приелась, тогда вам поручили задание создать новый вид пиццы.
Очевидно, что вы не будете с нуля создавать новую рецептуру пиццы, вы возьмёте старую сырную пиццу и добавите в неё томатов.
Только что вы применили наследование.
Каким должно было быть наследование?
Помните Айвена Сазерленда? Да-да, того самого, который создал приложение Sketchpad и использовал в нём первый известный объект.
Объекты представляли собой графические знаки, выводимые на экране осциллографа, и поддерживающие наследование через динамических делегатов,
которые он назвал в своей работе «мастер-объектами» (masters).
Любой объект мог стать мастер-объектом, дополнительные экземпляры объекта были названы «реализациями» (occurrences).
Да, именно наследование, правда тогда это было правильное(Именно такое наследование хотел видеть Алан Кей) наследование, которое называется прототипное наследование.
Прототипное наследование vs Классическое наследование(наследование которое мы имеем)
В классическом наследовании экземпляры наследуются от класса, и создают отношения между подклассами.
Другими словами, вы не можете использовать класс, также как вы использовали бы экземпляр.
В прототипном наследовании экземпляры наследуются от других экземпляров.
Используя прототипное наследование, вы просто копируете свойства из объекта в новый экземпляр.
У обоих подходов есть свои плюсы и минусы. Но самым главным различием между ними(кроме того что это два координально разных подхода) является, то
что при использовании прототипного наследования, не обязательно создавать иерархии классов, как побочный эффект при создании подклассов.
Дополнительные материалы
https://bit.ly/3Pobuv7
https://habr.com/ru/company/hexlet/blog/303754/
https://bit.ly/3NepPZ8
Wikipedia
Наследование (программирование)
механизм языка объектно-ориентированного программирования, позволяющий описать новый класс на основе уже существующего
❤2👍2🥰1
#ООП
Введение
Продолжая тему ООП. Сегодня мы рассмотрим вторую, самую сложную парадигму в данной методологии - инкапсуляцию.
Инкапсуляция
Вопрос: Почему же она самая сложная?
Ответ:
1. ИМХО В разных языках её можно определить по разному.
2. Есть достаточное количество неверных определений данной парадигмы.
Вот правильное определение инкапсуляции в питоне:
Инкапсуляция - это механизм языка позволяющий, объединить данные и методы, в единый компонент и скрыть детали реализации от пользователя.
Инкапсуляция как объединение
Пусть мы создали класс User. В нём мы создали поле name. Затем мы создали метод get_username, который возвращает значение поля name:
Только что мы увидели проявление инкапсуляции, как объединение данных и методов, где ввиде данных выступил атрибут.
Про уровни доступа
Модификаторы доступа — это чаще всего ключевые слова, которые регулируют уровень доступа к разным частям твоего кода.
В питоне в отличие от Java, C++ и многих других языков программирования, не существует уровней и модификаторов доступа вообще. А то что называют уровнями доступа в питоне - механизм и соглашение не совсем относящиеся к этой теме. Об этом механизме и соглашение мы поговорим ниже.
Атрибуты для "внутреннего использования"
Существует соглашение, что атрибуты, классы, методы и другие программные члены с одним подчёркиванием _ перед названием, из вне трогать не стоит, так как они предназначены для "внутреннего использования в классе" и они не являются частью API класса или модуля. Это соглашение никак не закреплено механизмами языка => программист если захочет может спокойно его нарушить. Данное соглашение позволяет условно разделить API класса и его внутренности.
name mangling
Иногда нам нужно сделать так, чтобы атрибут нельзя было переопределить в наследнике и к нему не было доступа из вне. Для таких ситуаций python предоставляет механизм под названием name mangling.
Чтобы использовать name mangling в питоне нужно поставить два подчеркивания перед именем атрибута.
При попытке получить доступ к защищённому нейм манглингом атрибуту вы получите ошибку.
Очевидно данный механизм тоже можно обойти.
Как обойти name mangling?
Питон предоставляет специальный синтаксис для обхода данного механизма.
Если мы хотим обойти name mangling атрибута:
Итоги
1. Управление доступом, никак не относится к инкапсуляции. Инкапсуляция это в первую очередь объединение данных и методов в единый компонент.
2. В питоне не существует никаких уровней и модификаторов доступа, а то что ими называют - механизмы и соглашения не относящиеся к этой теме.
3. Если вы хотите условно разделить публичное API и внутренности класса, то можно использовать соглашение о подчёркивание перед именем. Если же вы хотите чётко(так чтобы клиент не имел доступа к внутренностям) разделить публичное API и внутренности класса, то могу вам порекомендовать паттерн проектирования "Фасад".
4. Если вам нужно защитить атрибут от доступа из вне или переопределения, то можете использовать механизм name mangling.
Введение
Продолжая тему ООП. Сегодня мы рассмотрим вторую, самую сложную парадигму в данной методологии - инкапсуляцию.
Инкапсуляция
Вопрос: Почему же она самая сложная?
Ответ:
1. ИМХО В разных языках её можно определить по разному.
2. Есть достаточное количество неверных определений данной парадигмы.
Вот правильное определение инкапсуляции в питоне:
Инкапсуляция - это механизм языка позволяющий, объединить данные и методы, в единый компонент и скрыть детали реализации от пользователя.
Инкапсуляция как объединение
Пусть мы создали класс User. В нём мы создали поле name. Затем мы создали метод get_username, который возвращает значение поля name:
class User:
name = 'Mark'
def get_name(self) -> str:,
return self.name
Только что мы увидели проявление инкапсуляции, как объединение данных и методов, где ввиде данных выступил атрибут.
Про уровни доступа
Модификаторы доступа — это чаще всего ключевые слова, которые регулируют уровень доступа к разным частям твоего кода.
В питоне в отличие от Java, C++ и многих других языков программирования, не существует уровней и модификаторов доступа вообще. А то что называют уровнями доступа в питоне - механизм и соглашение не совсем относящиеся к этой теме. Об этом механизме и соглашение мы поговорим ниже.
Атрибуты для "внутреннего использования"
Существует соглашение, что атрибуты, классы, методы и другие программные члены с одним подчёркиванием _ перед названием, из вне трогать не стоит, так как они предназначены для "внутреннего использования в классе" и они не являются частью API класса или модуля. Это соглашение никак не закреплено механизмами языка => программист если захочет может спокойно его нарушить. Данное соглашение позволяет условно разделить API класса и его внутренности.
name mangling
Иногда нам нужно сделать так, чтобы атрибут нельзя было переопределить в наследнике и к нему не было доступа из вне. Для таких ситуаций python предоставляет механизм под названием name mangling.
Чтобы использовать name mangling в питоне нужно поставить два подчеркивания перед именем атрибута.
При попытке получить доступ к защищённому нейм манглингом атрибуту вы получите ошибку.
Очевидно данный механизм тоже можно обойти.
Как обойти name mangling?
Питон предоставляет специальный синтаксис для обхода данного механизма.
Если мы хотим обойти name mangling атрибута:
ИмяКласса._ИмяКласса__атрибут
Ес
ли мы хотим обойти name mangling метода:объект._ИмяКласса__метод
Итоги
1. Управление доступом, никак не относится к инкапсуляции. Инкапсуляция это в первую очередь объединение данных и методов в единый компонент.
2. В питоне не существует никаких уровней и модификаторов доступа, а то что ими называют - механизмы и соглашения не относящиеся к этой теме.
3. Если вы хотите условно разделить публичное API и внутренности класса, то можно использовать соглашение о подчёркивание перед именем. Если же вы хотите чётко(так чтобы клиент не имел доступа к внутренностям) разделить публичное API и внутренности класса, то могу вам порекомендовать паттерн проектирования "Фасад".
4. Если вам нужно защитить атрибут от доступа из вне или переопределения, то можете использовать механизм name mangling.
👍2
#ООП
Введение
Продолжая тему ООП. Сегодня мы рассмотрим третью парадигму в данной методологии - полиморфизм.
Полиморфизм
Полиморфизм заключается в использовании единственной сущности для представления различных типов в различных сценариях использования.
Всего существует три вида полиморфизма:
1. Полиморфизм подтипов
2. Параметрический полиморфизм
3. Ad-hoc полиморфизм
Полиморфизм подтипов
Полиморфизм подтипов заключается в том, что клиентский код который использует объект, опирается только на его интерфейс, не зная при этом фактического типа. Данный подход позволяет снизить количество написанного кода и соблюсти принцип DRY
Возможно это прозвучало сложно, однако полиморфизм проще понять на практике, поэтому давайте рассмотрим пример.
В данном примере мы с помощью полиморфизма подтипов мы можем обобщить вызов методов, игнорируя объект с которым мы работаем.
class Test1:
def do(self):
print(1)
class Test2:
def do(self):
print(2)
test1 = Test1()
test2 = Test2()
for _ in (test1, test2):
_.do()
Вывод:
1
2
Мы создали два очень похожих класса, которые имеют методы с одинаковым названием. А затем просто прошлись циклом по кортежу из экземпляров этих классов и вызвали метод do используя общую переменную "_" .
Мы никак не связывали их одним родителем и не соединили классы каким-либо другим способом. Это и есть проявление полиморфизма подтипов.
Параметрический полиморфизм
Параметрический полиморфизм в языках программирования и теории типов — свойство семантики системы типов, позволяющее обрабатывать значения разных типов идентичным образом, то есть исполнять физически один и тот же код для данных разных типов
К сожалению или счастью в питоне нету параметрического полиморфизма, так как в python нельзя написать несколько версий одной функции с одним и тем же именем, чтобы каждая принимала свой тип параметра.
Ad-hoc полиморфизм
Ad-hoc полиморфизм в питоне выражается ввиде перегрузки операторов.
Перегрузка операторов заключается в возможности одновременного существования в одной области видимости нескольких различных вариантов применения операторов, имеющих одно и то же имя, но различающихся типами параметров, к которым они применяются.
Пример перегрузке оператора:
Пусть мы создали объект Date с полем day. Теперь нам нужно сделать так, чтобы мы могли использовать оператор
Чтобы это сделать, нам нужно перегрузить оператор сложения, для этого в классе Date нужно создать магический(специальный) метод add.
Магические методы, это методы, позволяющие перегрузить оператор или метод(изменить поведение объекта на какое-либо действие над ним, например получение атрибута или прибавление числа).
Все магические методы обрамлены двумя подчёркиваниями с двух сторон.
Дополнительные материалы
https://bit.ly/3zdXWfX
https://bit.ly/38IM9vv
https://bit.ly/3Tpo4MA
Введение
Продолжая тему ООП. Сегодня мы рассмотрим третью парадигму в данной методологии - полиморфизм.
Полиморфизм
Полиморфизм заключается в использовании единственной сущности для представления различных типов в различных сценариях использования.
Всего существует три вида полиморфизма:
1. Полиморфизм подтипов
2. Параметрический полиморфизм
3. Ad-hoc полиморфизм
Полиморфизм подтипов
Полиморфизм подтипов заключается в том, что клиентский код который использует объект, опирается только на его интерфейс, не зная при этом фактического типа. Данный подход позволяет снизить количество написанного кода и соблюсти принцип DRY
Возможно это прозвучало сложно, однако полиморфизм проще понять на практике, поэтому давайте рассмотрим пример.
В данном примере мы с помощью полиморфизма подтипов мы можем обобщить вызов методов, игнорируя объект с которым мы работаем.
class Test1:
def do(self):
print(1)
class Test2:
def do(self):
print(2)
test1 = Test1()
test2 = Test2()
for _ in (test1, test2):
_.do()
Вывод:
1
2
Мы создали два очень похожих класса, которые имеют методы с одинаковым названием. А затем просто прошлись циклом по кортежу из экземпляров этих классов и вызвали метод do используя общую переменную "_" .
Мы никак не связывали их одним родителем и не соединили классы каким-либо другим способом. Это и есть проявление полиморфизма подтипов.
Параметрический полиморфизм
Параметрический полиморфизм в языках программирования и теории типов — свойство семантики системы типов, позволяющее обрабатывать значения разных типов идентичным образом, то есть исполнять физически один и тот же код для данных разных типов
К сожалению или счастью в питоне нету параметрического полиморфизма, так как в python нельзя написать несколько версий одной функции с одним и тем же именем, чтобы каждая принимала свой тип параметра.
Ad-hoc полиморфизм
Ad-hoc полиморфизм в питоне выражается ввиде перегрузки операторов.
Перегрузка операторов заключается в возможности одновременного существования в одной области видимости нескольких различных вариантов применения операторов, имеющих одно и то же имя, но различающихся типами параметров, к которым они применяются.
Пример перегрузке оператора:
Пусть мы создали объект Date с полем day. Теперь нам нужно сделать так, чтобы мы могли использовать оператор
"+"
к этому объекту и изменять поле day на прибавленное число.Чтобы это сделать, нам нужно перегрузить оператор сложения, для этого в классе Date нужно создать магический(специальный) метод add.
Магические методы, это методы, позволяющие перегрузить оператор или метод(изменить поведение объекта на какое-либо действие над ним, например получение атрибута или прибавление числа).
Все магические методы обрамлены двумя подчёркиваниями с двух сторон.
Дополнительные материалы
https://bit.ly/3zdXWfX
https://bit.ly/38IM9vv
https://bit.ly/3Tpo4MA
❤4👍2
#ООП
Введение
Продолжая тему ООП. Сегодня мы рассмотрим четвёртую парадигму в данной методологии - абстракцию.
Абстракция
Абстракция в ООП - это использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе.
Основная идея состоит в том, чтобы представить объект минимальным набором полей и методов и при этом с достаточной точностью для решаемой задачи.
Любой объект в реальном мире это абстракция. Когда мы говорим "клавиатура", мы не объясняем, что это объект состоящий из несколько видов пластика и
лампочек для подсветки.
Если говорить о примере абстракции в программирование, то давайте представим, что вы хотите
отправить http запрос, вы можете просто взять готовую библиотеку requests и получить высокоуровневый интерфейс,
который является абстракцией над HTTP протоколом и сетевым взаимодействием.
Как достичь абстракции в питоне?
Для достижения абстракции в питоне, вам потребуется библиотека abc(Abstract Base Classes), позволяющая
создавать абстрактные классы(если вы пришли в питон с другого языка, то могу сказать, что абстрактный класс очень похож на интерфейс).
Абстрактный класс
Абстрактный класс — базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП — полиморфизм.
Абстрактный класс может содержать абстрактные методы и свойства.
Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков.
Абстрактный метод - это метод, который обязан реализовать потомок абстрактного класса.
Грубо говоря абстрактный класс - это класс скелет на основе которого вы описываете, его потомков.
Дополнительные материалы
https://bit.ly/3x1IEs5
https://bit.ly/3wZeq93
https://bit.ly/3tcoLh0
Введение
Продолжая тему ООП. Сегодня мы рассмотрим четвёртую парадигму в данной методологии - абстракцию.
Абстракция
Абстракция в ООП - это использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе.
Основная идея состоит в том, чтобы представить объект минимальным набором полей и методов и при этом с достаточной точностью для решаемой задачи.
Любой объект в реальном мире это абстракция. Когда мы говорим "клавиатура", мы не объясняем, что это объект состоящий из несколько видов пластика и
лампочек для подсветки.
Если говорить о примере абстракции в программирование, то давайте представим, что вы хотите
отправить http запрос, вы можете просто взять готовую библиотеку requests и получить высокоуровневый интерфейс,
который является абстракцией над HTTP протоколом и сетевым взаимодействием.
Как достичь абстракции в питоне?
Для достижения абстракции в питоне, вам потребуется библиотека abc(Abstract Base Classes), позволяющая
создавать абстрактные классы(если вы пришли в питон с другого языка, то могу сказать, что абстрактный класс очень похож на интерфейс).
Абстрактный класс
Абстрактный класс — базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП — полиморфизм.
Абстрактный класс может содержать абстрактные методы и свойства.
Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков.
Абстрактный метод - это метод, который обязан реализовать потомок абстрактного класса.
Грубо говоря абстрактный класс - это класс скелет на основе которого вы описываете, его потомков.
Дополнительные материалы
https://bit.ly/3x1IEs5
https://bit.ly/3wZeq93
https://bit.ly/3tcoLh0
Wikipedia
Абстрактный класс
Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров. Абстрактные классы реализуют на практике один из принципов ООП — полиморфизм. Абстрактный класс может содержать (и не содержать )…
👍10
#тайпхинты
Введение
Немного отвлечёмся от ООП и рассмотрим очень важную тему в питоне - тайпхинты.
Типизация
Python - язык с динамической типизацией, позволяет нам не указывать тип переменной, однако такой подход бывает очень не удобен, ведь без указания типа, нам бывает очень сложно найти ошибку связанную с передачей типа.
Тайпхинты
На помощь приходят, тайпхинты! Python сохранил идею динамической, утиной типизации и с версии Python 3.6 начал поддерживать тайпхинты.
Тайпхинт, по своей сущности похож на комментарий, ведь интерпретатор никак не учитывает его. Кроме того, что тайпхинты помогают читать код, также их учитывают популярные IDE и линтеры.
Синтаксис тайпхинтов
Питон поддерживает тайпхинты для: аргументов функции, возвращаемых значений функции и атрибутов класса.
Подсказка типа для аргумента, переменной и атрибута имеет такой синтаксис:
название: тип
Дополнительные материалы
https://habr.com/ru/company/lamoda/blog/432656/
https://www.python.org/dev/peps/pep-3107/
https://www.python.org/dev/peps/pep-0526/
Введение
Немного отвлечёмся от ООП и рассмотрим очень важную тему в питоне - тайпхинты.
Типизация
Python - язык с динамической типизацией, позволяет нам не указывать тип переменной, однако такой подход бывает очень не удобен, ведь без указания типа, нам бывает очень сложно найти ошибку связанную с передачей типа.
Тайпхинты
На помощь приходят, тайпхинты! Python сохранил идею динамической, утиной типизации и с версии Python 3.6 начал поддерживать тайпхинты.
Тайпхинт, по своей сущности похож на комментарий, ведь интерпретатор никак не учитывает его. Кроме того, что тайпхинты помогают читать код, также их учитывают популярные IDE и линтеры.
Синтаксис тайпхинтов
Питон поддерживает тайпхинты для: аргументов функции, возвращаемых значений функции и атрибутов класса.
Подсказка типа для аргумента, переменной и атрибута имеет такой синтаксис:
название: тип
Примеры:
tes
t: int = 4
self.test: int = 4
def x(test: int):
Подсказка типа
для возвращаемого значения функции имеет такой синтаксис:def название(...) -> тип:
Пример:
def
test(...) -> int:
Дополнительные материалы
https://habr.com/ru/company/lamoda/blog/432656/
https://www.python.org/dev/peps/pep-3107/
https://www.python.org/dev/peps/pep-0526/
👍2
#тайпхинты
Введение
Продолжая тему тайпхинтов. Сегодня мы рассмотрим пакет typing, который добавляет много полезного функционала для тайпхинтов.
List, Tuple и Dict
Вы конечно можете использовать встроенные в питон типы list и tuple, однако, данные тайпхинты из пакета typing позволяют уточнить какие элементы хранятся в структуре.
Примеры:
Any
По названию данного тайпхинта понятно, что он показывает, что можно использовать любой тип.
Union
Для случаев, если необходимо допустить использование ограниченного количества типов, есть тайпхинт Union. Чтобы его использовать нужно указать в квадратных скобках допустимый список типов.
Пример:
UPD: в питоне 3.10 Union стал ненужным, так как появилась такая конструкция:
Optional
Optional - это тоже самое, что и Union[..., None] или ... | None.
С помощью Optional вы можете указать, что вы хотите, чтобы использовался не только указаный тип, но и None.
Пример:
NoReturn
NoReturn нужен, когда функция никогда не возвращает управление.
Примеры:
Iterable
Если функция является генераторной и содержит yield, нужно использовать тайпхинт Iterable.
Пример:
Дополнительные материалы
https://docs.python.org/3/library/typing.html
Введение
Продолжая тему тайпхинтов. Сегодня мы рассмотрим пакет typing, который добавляет много полезного функционала для тайпхинтов.
List, Tuple и Dict
Вы конечно можете использовать встроенные в питон типы list и tuple, однако, данные тайпхинты из пакета typing позволяют уточнить какие элементы хранятся в структуре.
Примеры:
List[int]
Tuple[int]
Dict[int, int]
Any
По названию данного тайпхинта понятно, что он показывает, что можно использовать любой тип.
Union
Для случаев, если необходимо допустить использование ограниченного количества типов, есть тайпхинт Union. Чтобы его использовать нужно указать в квадратных скобках допустимый список типов.
Пример:
Union[int, str]
UPD: в питоне 3.10 Union стал ненужным, так как появилась такая конструкция:
int | str
, которая делает тоже самое, что и этот тайпхинт!Optional
Optional - это тоже самое, что и Union[..., None] или ... | None.
С помощью Optional вы можете указать, что вы хотите, чтобы использовался не только указаный тип, но и None.
Пример:
Optional[int] # int | None
NoReturn
NoReturn нужен, когда функция никогда не возвращает управление.
Примеры:
def test() -> NoReturn:
sys.exit()
def test() -> NoReturn:
while True:
pass
Iterable
Если функция является генераторной и содержит yield, нужно использовать тайпхинт Iterable.
Пример:
def test() -> Iterable[int]:
yield 3
yield 4
Дополнительные материалы
https://docs.python.org/3/library/typing.html
🔥5👍1
#py2exe #pyinstsller #ошибки
Введение
Сегодня, я хотел бы разобрать такую библиотеку как pyinstaller, которая позволяет собирать python в exe.
Вопрос: "Почему я решил сделать этот пост?"
Ответ: "В последнее время, я заметил тенденцию того, что новички начали очень часто использовать pyinstaller для сборки exe, хотя данный инструмент несёт в себе только вред."
Процесс сборки exe
Как pyinstaller собирает exe(что-то похожее на него):,
Шаг 1: Считывает код файла
Шаг 2: Анализирует код, для получение всех зависимостей необходимых для работы
Шаг 3: Создаёт .spec файл конфигурации
Шаг 4: Собирает все файлы и добавляет к ним интерпретатор питона.
Шаг 5: Создаёт папку BUILD, куда записывает логи и рабочие файлы
Шаг 6: Создаёт папку DIST
Шаг 7: Записывает все необходимые файлы в одну папку или что-то похожее на exe.
Почему же он вреден?
1. Вес exe огромен
2. Это подобее exe пытается запустить то, что считало из себя, что может напоминать поведение троянов и как следствие вызывать подозрения у антивирусов
3. Если вы использовали флаг --onefile, то exe начинает очень сильно засорять парку tmp
4. Код никак не защищается(как думают многие не опытные программисты, для обфускации кода используйте pyarmor), даже если вы собирали pyc, а не py.
5. Огромное количество библиотек не работают в exe собранном данной библиотекой.
6. При сборке под линукс возникают проблемы с работой стандартной библиотеки.
Выводы
Pyinstaller - очень похож на обычный архиватор, который просто засовывает в исполняемый файл интерпретатор питона. Это самый плохой способ распространения программ на питоне.
Введение
Сегодня, я хотел бы разобрать такую библиотеку как pyinstaller, которая позволяет собирать python в exe.
Вопрос: "Почему я решил сделать этот пост?"
Ответ: "В последнее время, я заметил тенденцию того, что новички начали очень часто использовать pyinstaller для сборки exe, хотя данный инструмент несёт в себе только вред."
Процесс сборки exe
Как pyinstaller собирает exe(что-то похожее на него):,
Шаг 1: Считывает код файла
Шаг 2: Анализирует код, для получение всех зависимостей необходимых для работы
Шаг 3: Создаёт .spec файл конфигурации
Шаг 4: Собирает все файлы и добавляет к ним интерпретатор питона.
Шаг 5: Создаёт папку BUILD, куда записывает логи и рабочие файлы
Шаг 6: Создаёт папку DIST
Шаг 7: Записывает все необходимые файлы в одну папку или что-то похожее на exe.
Почему же он вреден?
1. Вес exe огромен
2. Это подобее exe пытается запустить то, что считало из себя, что может напоминать поведение троянов и как следствие вызывать подозрения у антивирусов
3. Если вы использовали флаг --onefile, то exe начинает очень сильно засорять парку tmp
4. Код никак не защищается(как думают многие не опытные программисты, для обфускации кода используйте pyarmor), даже если вы собирали pyc, а не py.
5. Огромное количество библиотек не работают в exe собранном данной библиотекой.
6. При сборке под линукс возникают проблемы с работой стандартной библиотеки.
Выводы
Pyinstaller - очень похож на обычный архиватор, который просто засовывает в исполняемый файл интерпретатор питона. Это самый плохой способ распространения программ на питоне.
👍12
#SOLID
Введение
Сегодня мы начнём очень важную и сложную тему в программировании - SOLID.
Что это такое и зачем это нужно?
SOLID - это 5 основных принципов ООП, предложенных Робертом Мартином, при соблюдении которых вы сможете без труда поддерживать и расширять вашу программу в течении долгого времени.
Расшифровка SOLID
S - single responsibility(принцип единой ответственности)
O - open-closed(принцип открытости закрытости)
L - Liskov substitution(принцип подстановки Барбары Лисков)
I - interface segregation(принцип разделения интерфейса)
D - dependency inversion(принцип инверсии зависимостей)
Дополнительные материалы
https://www.amazon.com/software-development-principles-razrabotka-printsipy/dp/5845905583
https://bit.ly/3NQQhs0
https://bit.ly/3auZM1D
Введение
Сегодня мы начнём очень важную и сложную тему в программировании - SOLID.
Что это такое и зачем это нужно?
SOLID - это 5 основных принципов ООП, предложенных Робертом Мартином, при соблюдении которых вы сможете без труда поддерживать и расширять вашу программу в течении долгого времени.
Расшифровка SOLID
S - single responsibility(принцип единой ответственности)
O - open-closed(принцип открытости закрытости)
L - Liskov substitution(принцип подстановки Барбары Лисков)
I - interface segregation(принцип разделения интерфейса)
D - dependency inversion(принцип инверсии зависимостей)
Дополнительные материалы
https://www.amazon.com/software-development-principles-razrabotka-printsipy/dp/5845905583
https://bit.ly/3NQQhs0
https://bit.ly/3auZM1D
👍5
#SOLID
Введение
Сегодня мы рассмотрим первый принцип SOLID - принцип единой ответственности.
Принцип единой ответственности
Данный принцип SOLID обозначает, что каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс. Все его поведения должны быть направлены исключительно на обеспечение этой ответственности.
Грубо говоря, данный принцип гласит, что каждый объект должен выполнять только свою задачу. Например, если объект Dog, не должен реализовать что-то из кошки или вовсе быть кошкой.
SRP — это принцип, объясняющий как декомпозировать, то есть где провести линию разделения.
Он говорит, что декомпозировать нужно по принципу разделения "ответственности", то есть по задачам тех или иных объектов.
Дополнительные материалы
https://bit.ly/3Q7ywqu
https://web-creator.ru/articles/solid_the_single_responsibility_principle
Введение
Сегодня мы рассмотрим первый принцип SOLID - принцип единой ответственности.
Принцип единой ответственности
Данный принцип SOLID обозначает, что каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс. Все его поведения должны быть направлены исключительно на обеспечение этой ответственности.
Грубо говоря, данный принцип гласит, что каждый объект должен выполнять только свою задачу. Например, если объект Dog, не должен реализовать что-то из кошки или вовсе быть кошкой.
SRP — это принцип, объясняющий как декомпозировать, то есть где провести линию разделения.
Он говорит, что декомпозировать нужно по принципу разделения "ответственности", то есть по задачам тех или иных объектов.
Дополнительные материалы
https://bit.ly/3Q7ywqu
https://web-creator.ru/articles/solid_the_single_responsibility_principle
Wikipedia
Принцип единственной ответственности
Принцип единственной ответственности (англ. single-responsibility principle, SRP) — принцип ООП, обозначающий, что каждый объект должен иметь одну ответственность и эта ответственность должна быть полностью инкапсулирована в класс. Все его поведения должны…
👍2
#SOLID #задача
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но закрыты для модификации."
Грубо говоря, следование данному принципу заключается в том, что программное обеспечение изменяется не через изменение существующего кода, а через добавление нового кода.
То есть, новая функциональность должна добавлятся не модифицированием старого кода.
Задача
Пусть у нас есть класс Discount, который позволяет выдавать скидки в вашем интернет магазине:
Этот код - пример нарушения принципа открытости/закрытости. Попробуйте исправить данную программу.
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но закрыты для модификации."
Грубо говоря, следование данному принципу заключается в том, что программное обеспечение изменяется не через изменение существующего кода, а через добавление нового кода.
То есть, новая функциональность должна добавлятся не модифицированием старого кода.
Задача
Пусть у нас есть класс Discount, который позволяет выдавать скидки в вашем интернет магазине:
class Discount:После некоторого времени работы вашего магазина, вы создали VIP карту, которую получили постоянные клиенты, данная карта увеличивает скидку на 20%, а значит нужно создать ещё одно условие, для проверки имеет ли пользователь вип карту. А что будет когда у вас появится ещё больше разновидностей скидок? Правильно, вам придётся писать всё новые и новые условия.
def __init__(self, customer: str, price: int | float):
self.customer = customer
self.price = price
def give_discount(self) -> int | float:
if self.customer == 'fav':
return self.price * 0.2
Этот код - пример нарушения принципа открытости/закрытости. Попробуйте исправить данную программу.
👍1
#SOLID #задача
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим третий принцип SOLID - принцип подстановки Барбары Лисков
Принцип подстановки Барбары Лисков
Барбара Лисков в 1987 году сформулировала данный принцип так:
Пример
Пусть у нас есть класс Vehicle, в котором мы создали метод
Дополнительные материалы
https://www.sicpers.info/2018/03/why-inheritance-never-made-any-sense/
http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим третий принцип SOLID - принцип подстановки Барбары Лисков
Принцип подстановки Барбары Лисков
Барбара Лисков в 1987 году сформулировала данный принцип так:
Пусть q(x) является свойством, верным относительно объектов x некоторого типа T. Тогда q(y) также должно быть верным для объектов y типа S, где S является подтипом типа T.
Звучит очень сложно, поэтому Роберт Мартин определил этот принцип так: Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.
Грубо говоря, идея Лисков заключается в том, что если S является наследником T, тогда объекты типа T в программе могут быть замещены объектами типа S без каких-либо последствий для работы программы.Пример
Пусть у нас есть класс Vehicle, в котором мы создали метод
start_engine
, в начале всё было замечательно мы создавали машины и мотоциклы, однако нам сказали сделать велосипед и в этот момент мы поняли, что нарушали LSP, ведь у велосипеда нет двигателя!class Vehicle:
def start_engine(self):
pass
class Car(Vehicle):
def start_engine(self):
pass
class Bicycle(Vehicle):
def start_engine(self):
pass
Попробуйте исправить данную программу и прислать решение в комментарии.Дополнительные материалы
https://www.sicpers.info/2018/03/why-inheritance-never-made-any-sense/
http://stephane.ducasse.free.fr/FreeBooks/BlueBook/Bluebook.pdf
👍6❤2
#SOLID
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим четвёртый принцип SOLID - принцип разделения интерфейса.
Принцип разделения интерфейса
Роберт Мартин определил этот принцип так:
Иногда кажется хорошей идеей объявить один большой абстрактный класс или интерфейс, а затем дать клиентам его реализовать.
Однако данный подход в корне не верен. Представим, что вам дали задание создать темплейт тг бота. Вы создаёте три абстрактных метода: send, start, save_data.
Когда клиент реализует все абстрактные методы, то всё нормально, но если клиенту не нужен метод сохранения в БД? Что ему делать? Здесь есть два варианты развития событий:
1. Поставить затычку.
2. Начать возмущаться - вызвать ошибку и добавить докстринг.
Рассмотрим первый кейс. Клиент поставил затычку, вроде бы всё хорошо, однако данный метод будет виден для пользователей ботов => пользователи будут использовать его и не понимать, в чём проблема.
Рассмотрим второй кейс. Клиент вызывает ошибку. Для маленького проекта может быть такой подход проблем не принесёт, клиент может открыть консоль и легко найти ошибку, но проблема становится серьёзнее, если данный код часть большого приложения.
Идея принципа разделения интерфейсов заключается в том, чтобы вы вместо реализации одного большого абстрактного класса с несколькими программными членами, стремились к детализации и старались разделить эту программную сущность на части, которые можно реализовать по отдельности.
Дополнительные материалы
https://web-creator.ru/articles/solid_the_interface_segregation_principle
https://bit.ly/3xOVLhP
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим четвёртый принцип SOLID - принцип разделения интерфейса.
Принцип разделения интерфейса
Роберт Мартин определил этот принцип так:
Программные сущности не должны зависеть от методов, которые они не используют.
Иногда кажется хорошей идеей объявить один большой абстрактный класс или интерфейс, а затем дать клиентам его реализовать.
Однако данный подход в корне не верен. Представим, что вам дали задание создать темплейт тг бота. Вы создаёте три абстрактных метода: send, start, save_data.
Когда клиент реализует все абстрактные методы, то всё нормально, но если клиенту не нужен метод сохранения в БД? Что ему делать? Здесь есть два варианты развития событий:
1. Поставить затычку.
2. Начать возмущаться - вызвать ошибку и добавить докстринг.
Рассмотрим первый кейс. Клиент поставил затычку, вроде бы всё хорошо, однако данный метод будет виден для пользователей ботов => пользователи будут использовать его и не понимать, в чём проблема.
Рассмотрим второй кейс. Клиент вызывает ошибку. Для маленького проекта может быть такой подход проблем не принесёт, клиент может открыть консоль и легко найти ошибку, но проблема становится серьёзнее, если данный код часть большого приложения.
Идея принципа разделения интерфейсов заключается в том, чтобы вы вместо реализации одного большого абстрактного класса с несколькими программными членами, стремились к детализации и старались разделить эту программную сущность на части, которые можно реализовать по отдельности.
Дополнительные материалы
https://web-creator.ru/articles/solid_the_interface_segregation_principle
https://bit.ly/3xOVLhP
Web Creator
Принципы SOLID: принцип разделения интерфейса
Принцип разделения интерфейса — один из пяти основных принципов объектно-ориентированного программирования и проектирования, сформулированных Робертом Мартином. Принцип в формулировке Роберта Мартина декларирует, что клиенты не должны зависеть от методов…
👍7❤2
#SOLID
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим последний принцип SOLID - принцип инверсии зависимостей.
Принцип инверсии зависимостей
Принцип инверсии зависимостей гласит:
Моду
Пример
Представим у вас есть программа, которая, готовит стейки.
Мы написали вот такой код:
Данная функция не только готовит мясо, но и создаёт его.
Это нарушает принцип инверсии зависимостей.
Функция cook зависит от Steak.
Теперь представим, что мы начали готовить курочку. Здесь многие модифицировали функцию cook условием, которое проверяет тип продукта. Данный подход в корне неверен ведь для каждого продукта придётся добавлять по условию, что нарушает все принципы.
Попробуйте исправить данный код используя абстракцию и прислать решения в комментарии.
Дополнительные материалы
https://bit.ly/3xTszq8
https://habr.com/ru/post/313796/
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим последний принцип SOLID - принцип инверсии зависимостей.
Принцип инверсии зависимостей
Принцип инверсии зависимостей гласит:
Моду
ли верхних уровней не должны импортировать сущности из модулей нижних уровней. Оба типа модулей должны зависеть от абстракций. Абстракции не должны зависеть от деталей Детали должны зависеть от абстракций.
Мо
дуль, может быть функцией, классом, файлом или просто фрагментом кода.Пример
Представим у вас есть программа, которая, готовит стейки.
Мы написали вот такой код:
def cook():
steak = Steak()
steak.cook()
Данная функция не только готовит мясо, но и создаёт его.
Это нарушает принцип инверсии зависимостей.
Функция cook зависит от Steak.
Теперь представим, что мы начали готовить курочку. Здесь многие модифицировали функцию cook условием, которое проверяет тип продукта. Данный подход в корне неверен ведь для каждого продукта придётся добавлять по условию, что нарушает все принципы.
Попробуйте исправить данный код используя абстракцию и прислать решения в комментарии.
Дополнительные материалы
https://bit.ly/3xTszq8
https://habr.com/ru/post/313796/
Wikipedia
Принцип инверсии зависимостей
Принцип инверсии зависимостей (англ. dependency inversion principle, DIP) — принцип объектно-ориентированного программирования, суть которого состоит в том, что классы должны зависеть от абстракций, а не от конкретных деталей . Используется для минимизации…
👍5
#DRY
Введение
Сегодня мы рассмотрим принцип разработки ПО DRY.
DRY
DRY расшифровывается как Don’t repeat yourself(Не повторяйте себя), данный принцип нацелен на снижения количества повторяющегося кода в программе.
Принцип DRY гласит:
Элементы должны изменятся просто и предсказуемо. Помимо использования методов и функций в коде, создатели принципа DRY рекомендуют использовать генераторы кода, автоматические системы компиляции.
Как соблюсти данный принцип и избежать излишней сложности?
Когда вы разрабатываете большой проект, вы можете столкнутся c избыточной сложностью реализации. Самое простое решение по уменьшению сложности - разделить систему на управляемые части(на мелкие, независимые части).
WET
Нарушения принципа DRY называют WET расшифровывается как Write Everything Twice или We enjoy typing. Здесь есть игра слов - DRY(сухой) и WET(мокрый).
Дополнительные материалы
https://habr.com/ru/post/144611/
https://bit.ly/3N2Thkq
Введение
Сегодня мы рассмотрим принцип разработки ПО DRY.
DRY
DRY расшифровывается как Don’t repeat yourself(Не повторяйте себя), данный принцип нацелен на снижения количества повторяющегося кода в программе.
Принцип DRY гласит:
Каждая
часть знания должна иметь единственное, непротиворечивое и авторитетное представление в рамках системы
Когда
принцип DRY применяется успешно, то изменение единственного элемента системы не требует внесения изменений в другие, логически не связанные элементы.Элементы должны изменятся просто и предсказуемо. Помимо использования методов и функций в коде, создатели принципа DRY рекомендуют использовать генераторы кода, автоматические системы компиляции.
Как соблюсти данный принцип и избежать излишней сложности?
Когда вы разрабатываете большой проект, вы можете столкнутся c избыточной сложностью реализации. Самое простое решение по уменьшению сложности - разделить систему на управляемые части(на мелкие, независимые части).
WET
Нарушения принципа DRY называют WET расшифровывается как Write Everything Twice или We enjoy typing. Здесь есть игра слов - DRY(сухой) и WET(мокрый).
Дополнительные материалы
https://habr.com/ru/post/144611/
https://bit.ly/3N2Thkq
Хабр
Три ключевых принципа ПО, которые вы должны понимать
Разрабатывая приложения, мы постоянно сталкиваемся с новыми подходами, языками и концептами. И постоянно мы мечемся в сомнениях «смогу ли я быть на волне, оставаться конкурентоспособным, учитывая все...
👍4❤1
#ошибки
Введение
Сегодня я бы хотел рассмотреть топ 3 самых частых проблем в коде новичков.
F строки .format или % в тексте для компьютера
Мы питон программисты, привыкли форматировать текст с помощью ф строк, .format или % - это очень удобно, а в случае с ф строками ещё и очень быстро.
Если с текстом, который получает человек всё довольно просто, то с текстом для компьютера могут возникнуть проблемы.
Весь текст, ожидаемый компьютером текст должен быть отформатирован согласно определённым правилам, поэтому мы
не можем без последствий вставить произвольную строку. Что я подразумеваю под "текстом для компьютера"?
URL, SQL, любые языки разметки, регулярные выражения, код на питоне и других ЯПах, команды shell. О каких последствиях идёт речь?
Последствия могут быть разные, от банального краша программы, до серьёзной утечки данных.
Разработка не тестируемого кода
Не задумываясь о том, как будет проходить тестирование кода, новички совершают ряд грубых ошибок,
которые перечислены в этом разделе:
1. Использование глобальных переменных
Казалась бы, они же упрощают жизнь, но нет, они приводят к усложнению кода,
неконтролируемому доступу и склеиванию с кодом инициализации. Так например, рассматривая код одного пет проекта, я
наткнулся на то, как человек из кнопки, делает SQL запрос.
2. config.py, settings.py, CFG, load_config
Я уверен, что все мои читатели когда-то создавали файлик и/или класс конфигурации и пихали туда
все константы и настройки. Так вот друзья, так делать вредно, ведь когда вы запустите тесты,
ваши настройки будут уже прочитаны, также для тестирования кода придётся часто их изменять.
3. Использование синглтона
Синглтон очень спорный паттерн, который лучше не использовать в коде дабы избежать проблем в будущем.
Данный паттерн нарушает принцип единой ответственности(так как кроме выполнения своей задачи, ещё и следит за наличием только одного экземпляра) и полностью противоречит природе тестов.
У каждого паттерна можно найти свои плюсы и минусы, однако синглтон - это исключение, так как его плюсы на самом деле и являются минусами.
Вывод: Не стоит использовать данный паттерн.
4. Использование функций высшего порядка там где они не нужны.
Вложенные функции невозможно протестировать и переиспользовать, поэтому использовать их нужно осторожно.
Всего я выделил 3 основных кейса, когда их использование необходимо:
1. Создание декоратора
2. Создание замыкания
3. Исключения, где без их использования нельзя создать нужное поведение в программе.
Использование ООП, где оно не нужно или использование псевдо ООП
Огромное количество новичков изучающих ООП начинают думать, что это обязательно
и весь код должен придерживаться данной методологии. Из таких соображении появляются классы, которые содержат одну функцию:
Вывод: Если вы пишите маленький калькулятор на 20 строк или генератор паролей на 2, то не надо использовать ООП!
Дополнительные материалы
https://t.me/advice17/6
https://t.me/advice17/5
https://github.com/bomzheg/aiogram_template/blob/master/app/
Введение
Сегодня я бы хотел рассмотреть топ 3 самых частых проблем в коде новичков.
F строки .format или % в тексте для компьютера
Мы питон программисты, привыкли форматировать текст с помощью ф строк, .format или % - это очень удобно, а в случае с ф строками ещё и очень быстро.
Если с текстом, который получает человек всё довольно просто, то с текстом для компьютера могут возникнуть проблемы.
Весь текст, ожидаемый компьютером текст должен быть отформатирован согласно определённым правилам, поэтому мы
не можем без последствий вставить произвольную строку. Что я подразумеваю под "текстом для компьютера"?
URL, SQL, любые языки разметки, регулярные выражения, код на питоне и других ЯПах, команды shell. О каких последствиях идёт речь?
Последствия могут быть разные, от банального краша программы, до серьёзной утечки данных.
Разработка не тестируемого кода
Не задумываясь о том, как будет проходить тестирование кода, новички совершают ряд грубых ошибок,
которые перечислены в этом разделе:
1. Использование глобальных переменных
Казалась бы, они же упрощают жизнь, но нет, они приводят к усложнению кода,
неконтролируемому доступу и склеиванию с кодом инициализации. Так например, рассматривая код одного пет проекта, я
наткнулся на то, как человек из кнопки, делает SQL запрос.
2. config.py, settings.py, CFG, load_config
Я уверен, что все мои читатели когда-то создавали файлик и/или класс конфигурации и пихали туда
все константы и настройки. Так вот друзья, так делать вредно, ведь когда вы запустите тесты,
ваши настройки будут уже прочитаны, также для тестирования кода придётся часто их изменять.
3. Использование синглтона
Синглтон очень спорный паттерн, который лучше не использовать в коде дабы избежать проблем в будущем.
Данный паттерн нарушает принцип единой ответственности(так как кроме выполнения своей задачи, ещё и следит за наличием только одного экземпляра) и полностью противоречит природе тестов.
У каждого паттерна можно найти свои плюсы и минусы, однако синглтон - это исключение, так как его плюсы на самом деле и являются минусами.
Вывод: Не стоит использовать данный паттерн.
4. Использование функций высшего порядка там где они не нужны.
Вложенные функции невозможно протестировать и переиспользовать, поэтому использовать их нужно осторожно.
Всего я выделил 3 основных кейса, когда их использование необходимо:
1. Создание декоратора
2. Создание замыкания
3. Исключения, где без их использования нельзя создать нужное поведение в программе.
Использование ООП, где оно не нужно или использование псевдо ООП
Огромное количество новичков изучающих ООП начинают думать, что это обязательно
и весь код должен придерживаться данной методологии. Из таких соображении появляются классы, которые содержат одну функцию:
class DeleteFile:
def delete(self):
....
Или процедурные куски кода засовываются в классы:class Int_input(object):
def new(cls, quest_text, error_text: str = 'Вы ввели некорректное число'):
return cls.int_input(quest_text, error_text)
@staticmethod
def int_input(quest_text, error_text):
while True:
a = input(quest_text)
try:
return int(a)
except ValueError:
print(error_text)
Вывод: Если вы пишите маленький калькулятор на 20 строк или генератор паролей на 2, то не надо использовать ООП!
Дополнительные материалы
https://t.me/advice17/6
https://t.me/advice17/5
https://github.com/bomzheg/aiogram_template/blob/master/app/
👍6🤮5❤1🤯1
#паттерны
Введение
Сегодня мы рассмотрим паттерны проектирования.
Паттерн проектирования - это повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.
Грубо говоря, это просто типичный способ решения задачи, который можно применять в дальнейшем.
Любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип её решения причём таким образом,
что это решение можно использовать миллион раз и при этом никакие две реализации не будут одинаковыми.
Виды паттернов
Паттерны делятся на 3 группы:
1. Поведенческие - паттерны проектирования, определяющие алгоритмы и способы реализации взаимодействия различных объектов и классов.
2. Порождающие - паттерны проектирования, которые имеют дело с процессом создания объектов.
3. Структурные - паттерны проектирования, в которых рассматривается вопрос о том, как из классов и объектов образуются более крупные структуры.
Когда использовать паттерн?
С паттернами нужно обращаться осторожно, ведь при не правильном использовании они могут очень сильно навредить.
Не нужно использовать паттерны просто так, чтобы они были в коде. Также, не стоит использовать паттерн, когда
он сильно усложняет весь код или приводит к нарушению какого-либо принципа ООП.
Паттерн можно использовать тогда и только тогда, когда задача, которую вам нужно решить, похожа на задачу, которую решает данный паттерн.
Анти-паттерны
Анти-паттерны - полная противоположность паттернам. Если паттерны проектирования - это примеры практик хорошего программирования,
то есть это правильные способы решения задачи, который можно применять в дальнейшем.
То анти-паттерны - это шаблоны ошибок, которые совершаются при решении различных задач.
Ресурсы по изучению паттернов
Легендарная книга Design Patterns от банды четырёх: https://www.ozon.ru/product/patterny-obektno-orientirovannogo-proektirovaniya-gamma-erih-helm-richard-174491298/?sh=EDT-TraCsw
Введение
Сегодня мы рассмотрим паттерны проектирования.
Паттерн проектирования - это повторяемая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста.
Грубо говоря, это просто типичный способ решения задачи, который можно применять в дальнейшем.
Любой паттерн описывает задачу, которая снова и снова возникает в нашей работе, а также принцип её решения причём таким образом,
что это решение можно использовать миллион раз и при этом никакие две реализации не будут одинаковыми.
Виды паттернов
Паттерны делятся на 3 группы:
1. Поведенческие - паттерны проектирования, определяющие алгоритмы и способы реализации взаимодействия различных объектов и классов.
2. Порождающие - паттерны проектирования, которые имеют дело с процессом создания объектов.
3. Структурные - паттерны проектирования, в которых рассматривается вопрос о том, как из классов и объектов образуются более крупные структуры.
Когда использовать паттерн?
С паттернами нужно обращаться осторожно, ведь при не правильном использовании они могут очень сильно навредить.
Не нужно использовать паттерны просто так, чтобы они были в коде. Также, не стоит использовать паттерн, когда
он сильно усложняет весь код или приводит к нарушению какого-либо принципа ООП.
Паттерн можно использовать тогда и только тогда, когда задача, которую вам нужно решить, похожа на задачу, которую решает данный паттерн.
Анти-паттерны
Анти-паттерны - полная противоположность паттернам. Если паттерны проектирования - это примеры практик хорошего программирования,
то есть это правильные способы решения задачи, который можно применять в дальнейшем.
То анти-паттерны - это шаблоны ошибок, которые совершаются при решении различных задач.
Ресурсы по изучению паттернов
Легендарная книга Design Patterns от банды четырёх: https://www.ozon.ru/product/patterny-obektno-orientirovannogo-proektirovaniya-gamma-erih-helm-richard-174491298/?sh=EDT-TraCsw
OZON
Паттерны объектно-ориентированного проектирования | Джонсон Ральф, Гамма Эрих - купить с доставкой по выгодным ценам в интернет…
Паттерны объектно-ориентированного проектирования | Джонсон Ральф, Гамма Эрих купить в интернет-магазине OZON по низким ценам! Бесплатная доставка🚚 ✔Фото ✔Скидки ✔Рассрочка и настоящие отзывы (174491298)
❤5👍2
#паттерны
Введение
Сегодня мы рассмотрим наш первый паттерн проектирования - стратегия.
Классификация
Тип: Поведенческий
Определение: Стратегия - это поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
Грубо говоря, его задача - выделить схожие алгоритмы, решающие конкретную задачу.
Данный паттерн дает возможность в процессе выполнения выбрать стратегию (алгоритм, инструмент, подход) решения задачи.
Как работает стратегия
Вместо того, чтобы один большой класс выполнял все задачи, он делегирует их классам стратегием, этот класс называется контекстом.
Стратегии реализуют различные варианты алгоритма.
Клиент должен создать объект стратегию и передать её в контекст.
Чтобы сменить стратегию нужно будет всего лишь изменить объект стратегию в контексте.
Клиент будет вызывать нужные ему методу у контекста, а контекст будет делегировать их на стратегии.
Важное уточнение: Все стратегии должны быть унаследованы от одного абстрактного класса, чтобы контекст был независимым.
Плюсы данного паттерна:
Возможность замены алгоритмов на лету.
Реализует принцип открытости/закрытости
Уходит от наследования к делегированию
Предоставляет разделение между моделью и представлением
Минусы данного паттерна:
Клиент должен знать в чем разница между стратегиями.
Усложняет программу, из-за добавления новых классов.
Пример:
Возьмём довольно просто пример. Пусть у нас есть некий элемент, который нужно провалидировать по определённому правилу, однако каким будет данное правило неизвестно, при этом надо написать код так, чтобы в будущем он не нарушал принцип открытости/закрытости и его было бы удобно расширять.
Задача
Придумайте несколько возможных вариантов валидации данных и реализуйте стратегию для примера, который дан выше.
Дополнительные материалы
https://refactoring.guru/ru/design-patterns/strategy
https://habr.com/ru/post/487858/
Введение
Сегодня мы рассмотрим наш первый паттерн проектирования - стратегия.
Классификация
Тип: Поведенческий
Определение: Стратегия - это поведенческий паттерн проектирования, который определяет семейство схожих алгоритмов и помещает каждый из них в собственный класс, после чего алгоритмы можно взаимозаменять прямо во время исполнения программы.
Грубо говоря, его задача - выделить схожие алгоритмы, решающие конкретную задачу.
Данный паттерн дает возможность в процессе выполнения выбрать стратегию (алгоритм, инструмент, подход) решения задачи.
Как работает стратегия
Вместо того, чтобы один большой класс выполнял все задачи, он делегирует их классам стратегием, этот класс называется контекстом.
Стратегии реализуют различные варианты алгоритма.
Клиент должен создать объект стратегию и передать её в контекст.
Чтобы сменить стратегию нужно будет всего лишь изменить объект стратегию в контексте.
Клиент будет вызывать нужные ему методу у контекста, а контекст будет делегировать их на стратегии.
Важное уточнение: Все стратегии должны быть унаследованы от одного абстрактного класса, чтобы контекст был независимым.
Плюсы данного паттерна:
Возможность замены алгоритмов на лету.
Реализует принцип открытости/закрытости
Уходит от наследования к делегированию
Предоставляет разделение между моделью и представлением
Минусы данного паттерна:
Клиент должен знать в чем разница между стратегиями.
Усложняет программу, из-за добавления новых классов.
Пример:
Возьмём довольно просто пример. Пусть у нас есть некий элемент, который нужно провалидировать по определённому правилу, однако каким будет данное правило неизвестно, при этом надо написать код так, чтобы в будущем он не нарушал принцип открытости/закрытости и его было бы удобно расширять.
Задача
Придумайте несколько возможных вариантов валидации данных и реализуйте стратегию для примера, который дан выше.
Дополнительные материалы
https://refactoring.guru/ru/design-patterns/strategy
https://habr.com/ru/post/487858/
Telegram
Holy Python
#SOLID #задача
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но…
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но…
❤5👍1
#паттерны
Введение
Сегодня мы рассмотрим паттерн проектирования "Фабричный метод".
Классификация
Тип: Порождающий
Определение: Фабричный метод - это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в родителе, позволяя подклассам изменять тип создаваемых объектов.
Грубо говоря, это шаблон проектирования, который помогает решить проблему создания различных объектов в зависимости от некоторых условий.
Фабричный метод позволяет классу делегировать, создание экземпляров подклассу.
Из чего состоит и как работает паттерн фабричный метод
1. Абстрактный класс/Интерфейс "создатель" - содержит фабричный метод и метод содержащий базовую бизнес логику, которая основана на объектах, возвращаемых фабричным методом. Метод с бизнес логикой обычно содержит вызов фабричного метода и некую работу с объектом, который вернул фабричный метод:
2. Абстрактный класс/Интерфейс "продукт" - методы которого реализуют конкретные продукты:
Избавляет класс от привязки к конкретным классам продуктов.
Упрощает поддержку кода.
Реализует принцип открытости/закрытости
Минусы данного паттерна:
Может привести к созданию больших параллельных иерархий классов.
Пример и задача:
Возьмём классический пример - пиццерия. Вам нужно реализовать паттерн фабричный метод, для пиццерии в которой готовится пицца и кальцоне двух видов - сырныя и томатная. Если хотите усложнить данную задачу, то придумайте некую бизнес логику, которая будет происходить с экземплярами, создаваемыми фабричным методом.
Пример из реального кода
Данный пример предоставил @Tishka17
https://github.com/Tishka17/dataclass_rest/blob/master/dataclass_rest/base.py#L24
Вот его объяснение какую задачу фабричный метод решает в данном случае: Это универсальный клиент для рестапишек. Ты реализуешь конкретные методы путем наследования и соответсвенно есть фабричный метод для создания конвертера (Factory из dataclass-factory)
Введение
Сегодня мы рассмотрим паттерн проектирования "Фабричный метод".
Классификация
Тип: Порождающий
Определение: Фабричный метод - это порождающий паттерн проектирования, который определяет общий интерфейс для создания объектов в родителе, позволяя подклассам изменять тип создаваемых объектов.
Грубо говоря, это шаблон проектирования, который помогает решить проблему создания различных объектов в зависимости от некоторых условий.
Фабричный метод позволяет классу делегировать, создание экземпляров подклассу.
Из чего состоит и как работает паттерн фабричный метод
1. Абстрактный класс/Интерфейс "создатель" - содержит фабричный метод и метод содержащий базовую бизнес логику, которая основана на объектах, возвращаемых фабричным методом. Метод с бизнес логикой обычно содержит вызов фабричного метода и некую работу с объектом, который вернул фабричный метод:
class BaseCreator(ABC):
@abstractmethod
def fabric_method(self):
"""
Return concrete product.
"""
def operation(self):
# Here some buiesness logic.
product = self
.fabric_method()
2. Абстрактный класс/Интерфейс "продукт" - методы которого реализуют конкретные продукты:
class BaseProduct(ABC):
@abstractmethod
def operation(self):
pass
3. Конкретные классы создатели и конкретные классы продуктов:class ConcreteProduct1(BaseProduct):
def operation(self):
return "{Result of the ConcreteProduct1}"
class ConcreteProduct2(BaseProduct):
def operation(self):
return "{Result of the ConcreteProduct2}"
class ConcreteFactory1(BaseFactory):
def fabric_method(self):
return ConcreteProduct1()
class ConcreteFactory2(BaseFactory):
def fabric_method(self):
return ConcreteProduct2()
Плюсы данного паттерна:Избавляет класс от привязки к конкретным классам продуктов.
Упрощает поддержку кода.
Реализует принцип открытости/закрытости
Минусы данного паттерна:
Может привести к созданию больших параллельных иерархий классов.
Пример и задача:
Возьмём классический пример - пиццерия. Вам нужно реализовать паттерн фабричный метод, для пиццерии в которой готовится пицца и кальцоне двух видов - сырныя и томатная. Если хотите усложнить данную задачу, то придумайте некую бизнес логику, которая будет происходить с экземплярами, создаваемыми фабричным методом.
Пример из реального кода
Данный пример предоставил @Tishka17
https://github.com/Tishka17/dataclass_rest/blob/master/dataclass_rest/base.py#L24
Вот его объяснение какую задачу фабричный метод решает в данном случае: Это универсальный клиент для рестапишек. Ты реализуешь конкретные методы путем наследования и соответсвенно есть фабричный метод для создания конвертера (Factory из dataclass-factory)
Telegram
Holy Python
#SOLID #задача
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но…
Введение
Продолжая тему SOLID. Сегодня мы рассмотрим второй принцип SOLID - принцип открытости/закрытости.
Принцип открытости/закрытости
Принцип открытости/закрытости гласит: "Программные сущности должны быть открыты для расширения, но…
👍6🔥6
Понятны ли вам посты по паттернам? Если нет, напишите в комментариях почему.
Anonymous Poll
20%
Да
20%
Нет
59%
Я оладушек
👍7
Навигация
Посты про ООП - #ООП
Посты про SOLID - #SOLID
Посты про ошибки и антипаттерны - #ошибки
Посты про паттерны проектирования - #паттерны
Посты про тайпхинты - #тайпхинты
Посты с задачами - #задача
Посты с исследованиями - #исследование
Посты про ООП - #ООП
Посты про SOLID - #SOLID
Посты про ошибки и антипаттерны - #ошибки
Посты про паттерны проектирования - #паттерны
Посты про тайпхинты - #тайпхинты
Посты с задачами - #задача
Посты с исследованиями - #исследование
🔥9👍3
#паттерны
Введение
Сегодня мы рассмотрим паттерн проектирования "Строитель".
Классификация
Тип: Порождающий
Определение: Отделяет конструирование сложного объекта от его представления, так, что в результате одного и того же процесса конструирования могут получатся разные представления.
Строитель заменяет огромный метод инициализации, на класс со специальными методами, вызывая которые, вы создадите объект.
Данный паттерн позволяет пошагово инициализировать большие объекты!
Главное отличие «строителя» от «фабрики» — это то, что она используется, когда создание занимает один шаг, а «строитель» применяется при множестве шагов.
Из чего состоит и как работает паттерн строитель
1. Абстрактный класс/Интерфейс "Builder", содержит методы, которые должны быть реализованы в классе строитель.
3. Классы описывающие объекты, которые нужны для создания сложного объекта.
4. Класс строителя
Плюсы данного паттерна
Позволяет создавать объекты пошагово.
Сокращает количество написанного кода и повышает читаемость
Изолирует код реализующий конструирование и представление.
Минусы данного паттерна
1. Процесс конструирования должен обеспечивать различные представления конструируемого объекта.
2. Алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой.
Пример и задача:
Сегодня возьмем довольно простой пример - машина. Вам нужно реализовать паттерн строитель который будет собирать машину.
Дополнительные материалы
https://m.youtube.com/watch?v=x5yGIuf13Rk1
https://bit.ly/3O7V8oB
Введение
Сегодня мы рассмотрим паттерн проектирования "Строитель".
Классификация
Тип: Порождающий
Определение: Отделяет конструирование сложного объекта от его представления, так, что в результате одного и того же процесса конструирования могут получатся разные представления.
Строитель заменяет огромный метод инициализации, на класс со специальными методами, вызывая которые, вы создадите объект.
Данный паттерн позволяет пошагово инициализировать большие объекты!
Главное отличие «строителя» от «фабрики» — это то, что она используется, когда создание занимает один шаг, а «строитель» применяется при множестве шагов.
Из чего состоит и как работает паттерн строитель
1. Абстрактный класс/Интерфейс "Builder", содержит методы, которые должны быть реализованы в классе строитель.
class BaseBuilder(ABC):
@abstractmethod
def test1(self):
"""Return Test1 object"""
@abstractmethod
def test2(self):
"""Return Test1 object"""
@abstractmethod
def create_test(self):
"""Create test object"""
2.
Класс описывающий сложный объект который мы хотим создать.class MyTest:
def init(self, test1: object, test2: object):
self.test1 = test1
self.test2 = test2
# Any methods that these object need.
def do(self):
...
3. Классы описывающие объекты, которые нужны для создания сложного объекта.
class Test1:
... # Here some logic
class Test2:
... # Here some logic
4. Класс строителя
class Builder(BaseBuilder):
def test1(self):
return Test1()
def test2(self):
return Test2()
def build_test(self):
test1 = self.test1()
test2 = self.test2()
return MyTest(test1, test2)
Плюсы данного паттерна
Позволяет создавать объекты пошагово.
Сокращает количество написанного кода и повышает читаемость
Изолирует код реализующий конструирование и представление.
Минусы данного паттерна
1. Процесс конструирования должен обеспечивать различные представления конструируемого объекта.
2. Алгоритм создания сложного объекта не должен зависеть от того, из каких частей состоит объект и как они стыкуются между собой.
Пример и задача:
Сегодня возьмем довольно простой пример - машина. Вам нужно реализовать паттерн строитель который будет собирать машину.
Дополнительные материалы
https://m.youtube.com/watch?v=x5yGIuf13Rk1
https://bit.ly/3O7V8oB
👍3