Python | Вопросы собесов
13.9K subscribers
38 photos
1 file
930 links
Cайт: easyoffer.ru
Реклама: @easyoffer_adv
ВП: @easyoffer_vp

Тесты t.me/+20tRfhrwPpM4NDQy
Задачи t.me/+nsl4meWmhfQwNDVi
Вакансии t.me/+cXGKkrOY2-w3ZTky
Download Telegram
🤔 Чем обычный метод отличается от class method?

Обычные методы и методы класса в Python различаются в основном тем, к чему они привязаны и как используются. Давайте рассмотрим их отличия более подробно.

🚩Обычные методы (Instance Methods)

Привязка к экземпляру:
🟠Обычные методы работают с конкретными экземплярами класса.
🟠Они принимают первым аргументом self, который указывает на текущий экземпляр класса.

Использование атрибутов: Могут изменять состояние экземпляра, то есть работать с его атрибутами.

Определение:
   class MyClass:
def instance_method(self, value):
self.value = value


Вызов:
   instance = MyClass()
instance.instance_method(10)


Пример:
class Dog:
def __init__(self, name):
self.name = name

def bark(self):
print(f"{self.name} говорит: Гав-гав!")

dog = Dog("Бобик")
dog.bark() # Вывод: Бобик говорит: Гав-гав!


🚩Методы класса (Class Methods)

Привязка к классу:
🟠Методы класса работают с самим классом и его атрибутами.
🟠Они принимают первым аргументом cls, который указывает на сам класс.

Использование атрибутов: Могут изменять состояние класса, то есть работать с атрибутами класса.

Определение:
   class MyClass:
class_variable = 0

@classmethod
def class_method(cls, value):
cls.class_variable = value


Вызов: Могут вызываться как через сам класс, так и через его экземпляры.
   MyClass.class_method(10)
instance = MyClass()
instance.class_method(20)


Пример:
class Dog:
total_dogs = 0

def __init__(self, name):
self.name = name
Dog.total_dogs += 1

@classmethod
def get_total_dogs(cls):
return cls.total_dogs

dog1 = Dog("Бобик")
dog2 = Dog("Шарик")
print(Dog.get_total_dogs()) # Вывод: 2


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍201
🤔 Что такое dependency injection?

Внедрение зависимостей (Dependency Injection, DI) — это дизайн-паттерн, используемый в объектно-ориентированном программировании для управления зависимостями между объектами. Внедрение зависимостей позволяет сделать код более гибким, тестируемым и поддерживаемым, отделяя создание объектов от их использования.

🚩Основные концепции

🟠Зависимости: Это объекты, от которых зависит класс. Например, если класс Car использует объект Engine, то Engine является зависимостью для Car.
🟠Внедрение: Процесс передачи зависимостей классу. Вместо того чтобы создавать зависимости внутри класса, они передаются извне.

🚩Преимущества внедрения зависимостей

🟠Снижение связности: Классы меньше зависят друг от друга, что упрощает их замену или модификацию.
🟠Упрощение тестирования: Легче подменять реальные зависимости на моки или стабы для написания тестов.
🟠Улучшение читаемости и поддержки кода: Код становится более модульным и легче поддерживается.

🚩Типы внедрения зависимостей

🟠Внедрение через конструктор: Зависимости передаются через параметры конструктора.
🟠Внедрение через методы (или сеттеры): Зависимости передаются через специальные методы.
🟠Внедрение через свойства: Зависимости назначаются через свойства объекта.

Рассмотрим пример, где класс Car зависит от класса Engine.
class Engine:
def start(self):
print("Engine started")

class Car:
def __init__(self, engine):
self.engine = engine

def start(self):
self.engine.start()
print("Car started")

# Создание объекта Engine
engine = Engine()

# Внедрение зависимости Engine в объект Car через конструктор
car = Car(engine)
car.start()


Внедрения через методы (сеттеры)
class Engine:
def start(self):
print("Engine started")

class Car:
def __init__(self):
self.engine = None

def set_engine(self, engine):
self.engine = engine

def start(self):
if self.engine is not None:
self.engine.start()
print("Car started")
else:
print("No engine to start")

# Создание объекта Engine
engine = Engine()

# Создание объекта Car
car = Car()

# Внедрение зависимости Engine в объект Car через метод
car.set_engine(engine)
car.start()


Внедрения через свойства
class Engine:
def start(self):
print("Engine started")

class Car:
def __init__(self):
self._engine = None

@property
def engine(self):
return self._engine

@engine.setter
def engine(self, engine):
self._engine = engine

def start(self):
if self._engine is not None:
self._engine.start()
print("Car started")
else:
print("No engine to start")

# Создание объекта Engine
engine = Engine()

# Создание объекта Car
car = Car()

# Внедрение зависимости Engine в объект Car через свойство
car.engine = engine
car.start()


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍122
🤔 Что будет, если в родительских классах есть функции с одинаковым названием?

Когда в Python используется наследование, и у родительских классов есть методы с одинаковым названием, происходит так называемое разрешение имен. Поведение зависит от способа вызова метода и от того, как определены классы.

🚩Множественное наследование и порядок разрешения методов (MRO)

Если у вас есть множественное наследование, то порядок разрешения методов (MRO, Method Resolution Order) определяет, какой метод будет вызван. Python использует алгоритм C3-линеаризации для вычисления MRO.
class A:
def say_hello(self):
print("Hello from A")

class B:
def say_hello(self):
print("Hello from B")

class C(A, B):
pass

c = C()
c.say_hello()


🚩Порядок разрешения методов (MRO)

В примере выше класс C наследует от классов A и B. Метод say_hello есть в обоих родительских классах. Порядок разрешения методов в классе C будет таким: C -> A -> B. Чтобы увидеть MRO, можно использовать метод __mro__ или функцию mro():
print(C.__mro__)
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

print(C.mro())
# [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]


Таким образом, при вызове c.say_hello() будет вызван метод say_hello класса A, так как он идет первым в MRO.

🚩Пример с переопределением метода в дочернем классе

Если вы переопределите метод в дочернем классе, то будет вызван метод, определенный в самом дочернем классе:
class A:
def say_hello(self):
print("Hello from A")

class B:
def say_hello(self):
print("Hello from B")

class C(A, B):
def say_hello(self):
print("Hello from C")

c = C()
c.say_hello()
# Вывод: Hello from C


🚩Вызов методов родительских классов с использованием super()

Иногда необходимо явно вызвать метод одного из родительских классов. Для этого используется функция super(), которая возвращает объект, через который можно вызывать методы родительского класса.
class A:
def say_hello(self):
print("Hello from A")

class B:
def say_hello(self):
print("Hello from B")

class C(A, B):
def say_hello(self):
super().say_hello()
print("Hello from C")

c = C()
c.say_hello()
# Вывод:
# Hello from A
# Hello from C


🚩Вызов методов конкретных родительских классов

Можно вызвать его напрямую через имя класса:
class A:
def say_hello(self):
print("Hello from A")

class B:
def say_hello(self):
print("Hello from B")

class C(A, B):
def say_hello(self):
A.say_hello(self)
B.say_hello(self)
print("Hello from C")

c = C()
c.say_hello()
# Вывод:
# Hello from A
# Hello from B
# Hello from C


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25🔥1
🤔 Что такое code cohesion & code coupling?

Когезия (cohesion) и связность (coupling) — это два важных концепта в программировании, которые влияют на качество и структуру кода.

🚩Когезия (Cohesion)

Когезия относится к степени, в которой элементы внутри модуля (например, класса или функции) связаны друг с другом и работают вместе для выполнения одной задачи. Высокая когезия означает, что элементы модуля сильно связаны и направлены на выполнение одной функции, что делает модуль более понятным и легким для сопровождения.

Класс, выполняющий одну задачу:
class FileHandler:
def read_file(self, filename):
with open(filename, 'r') as file:
return file.read()

def write_file(self, filename, data):
with open(filename, 'w') as file:
file.write(data)


Функция, выполняющая одну конкретную задачу:
def calculate_sum(numbers):
return sum(numbers)


Преимущества высокой когезии:
🟠Улучшенная читабельность и понятность кода.
🟠Легкость сопровождения и изменения.
🟠Повышенная вероятность повторного использования модулей.

🚩Связность (Coupling)

Связность относится к степени зависимости одного модуля от другого. Высокая связность означает, что модули сильно зависят друг от друга, что делает систему более жесткой и сложной для сопровождения. Низкая связность, напротив, означает, что модули имеют минимальные зависимости друг от друга, что делает систему более гибкой и легко модифицируемой.

Использование интерфейсов или абстракций:
class Database:
def connect(self):
pass

class MySQLDatabase(Database):
def connect(self):
print("Connecting to MySQL database")

class PostgreSQLDatabase(Database):
def connect(self):
print("Connecting to PostgreSQL database")

def initialize_db(db: Database):
db.connect()

db = MySQLDatabase()
initialize_db(db)


Внедрение зависимостей:
class Service:
def __init__(self, repository):
self.repository = repository

def perform_action(self):
self.repository.save("Some data")

class Repository:
def save(self, data):
print(f"Saving {data}")

repository = Repository()
service = Service(repository)
service.perform_action()


Преимущества низкой связности:
🟠 Легкость сопровождения и тестирования.
🟠 Улучшенная гибкость и расширяемость системы.
🟠 Возможность повторного использования модулей в разных контекстах.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15😁1
🤔 Что такое порождающий паттерн?

Порождающие паттерны (creational patterns) — это шаблоны проектирования в объектно-ориентированном программировании, которые предназначены для управления процессом создания объектов.

🚩Основные порождающие паттерны

🟠Одиночка (Singleton)
🟠Фабричный метод (Factory Method)
🟠Абстрактная фабрика (Abstract Factory)
🟠Строитель (Builder)
🟠Прототип (Prototype)

Одиночка (Singleton): Паттерн Одиночка гарантирует, что у класса будет только один экземпляр, и предоставляет глобальную точку доступа к нему.
class Singleton:
_instance = None

def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance

singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2) # True


Фабричный метод (Factory Method): Фабричный метод определяет интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемых объектов.
class Animal:
def speak(self):
raise NotImplementedError("Subclass must implement abstract method")

class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"

class AnimalFactory:
@staticmethod
def get_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
return None

dog = AnimalFactory.get_animal("dog")
cat = AnimalFactory.get_animal("cat")
print(dog.speak()) # Woof!
print(cat.speak()) # Meow!


Абстрактная фабрика (Abstract Factory): Абстрактная фабрика предоставляет интерфейс для создания семейств связанных или зависимых объектов без указания их конкретных классов.
class Dog:
def speak(self):
return "Woof!"

class Cat:
def speak(self):
return "Meow!"

class PetFactory:
def create_dog(self):
return Dog()

def create_cat(self):
return Cat()

factory = PetFactory()
dog = factory.create_dog()
cat = factory.create_cat()
print(dog.speak()) # Woof!
print(cat.speak()) # Meow!


Строитель (Builder): Паттерн Строитель используется для создания сложных объектов пошагово. Он позволяет создавать разные представления объекта, используя один и тот же код.
class House:
def __init__(self):
self.walls = None
self.roof = None
self.windows = None

def __str__(self):
return f"House with {self.walls} walls, {self.roof} roof, and {self.windows} windows."

class HouseBuilder:
def __init__(self):
self.house = House()

def build_walls(self, walls):
self.house.walls = walls
return self

def build_roof(self, roof):
self.house.roof = roof
return self

def build_windows(self, windows):
self.house.windows = windows
return self

def build(self):
return self.house

builder = HouseBuilder()
house = builder.build_walls("brick").build_roof("tile").build_windows("double-glazed").build()
print(house)
# House with brick walls, tile roof, and double-glazed windows.


Прототип (Prototype): Паттерн Прототип создает новые объекты путем копирования существующих экземпляров (прототипов).
import copy

class Prototype:
def __init__(self, value):
self.value = value

def clone(self):
return copy.deepcopy(self)

original = Prototype(10)
clone = original.clone()
print(original.value) # 10
print(clone.value) # 10
clone.value = 20
print(original.value) # 10
print(clone.value) # 20


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍262
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔 Что такое абстрактная фабрика?

Абстрактная фабрика (Abstract Factory) — это порождающий паттерн проектирования, который предоставляет интерфейс для создания семейств взаимосвязанных или взаимозависимых объектов без указания их конкретных классов. Этот паттерн позволяет создавать комплекты объектов, которые должны работать вместе, обеспечивая при этом их взаимозаменяемость.

🚩Основные концепции

🟠Абстрактная фабрика (Abstract Factory): Интерфейс или базовый класс с методами для создания различных продуктов (объектов).
🟠Конкретные фабрики (Concrete Factories): Реализации абстрактной фабрики, создающие конкретные продукты.
🟠Абстрактные продукты (Abstract Products): Интерфейсы или базовые классы для продуктов, которые создаются фабриками.
🟠Конкретные продукты (Concrete Products): Реализации абстрактных продуктов.

Создание абстрактных продуктов: Рассмотрим пример, в котором абстрактная фабрика создает различные виды кнопок и чекбоксов для двух разных операционных систем: Windows и MacOS.
from abc import ABC, abstractmethod

class Button(ABC):
@abstractmethod
def click(self):
pass

class Checkbox(ABC):
@abstractmethod
def check(self):
pass


Создание конкретных продуктов
class WindowsButton(Button):
def click(self):
print("Windows button clicked")

class MacOSButton(Button):
def click(self):
print("MacOS button clicked")

class WindowsCheckbox(Checkbox):
def check(self):
print("Windows checkbox checked")

class MacOSCheckbox(Checkbox):
def check(self):
print("MacOS checkbox checked")


Создание абстрактной фабрики
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button:
pass

@abstractmethod
def create_checkbox(self) -> Checkbox:
pass


Создание конкретных фабрик
class WindowsFactory(GUIFactory):
def create_button(self) -> Button:
return WindowsButton()

def create_checkbox(self) -> Checkbox:
return WindowsCheckbox()

class MacOSFactory(GUIFactory):
def create_button(self) -> Button:
return MacOSButton()

def create_checkbox(self) -> Checkbox:
return MacOSCheckbox()


Использование абстрактной фабрики
def client_code(factory: GUIFactory):
button = factory.create_button()
checkbox = factory.create_checkbox()
button.click()
checkbox.check()

# Клиентский код может работать с любыми фабриками и продуктами
windows_factory = WindowsFactory()
macos_factory = MacOSFactory()

print("Client: Testing client code with Windows factory:")
client_code(windows_factory)

print("\nClient: Testing client code with MacOS factory:")
client_code(macos_factory)


🚩Преимущества абстрактной фабрики

🟠Изоляция конкретных классов: Клиентский код работает только с интерфейсами или абстрактными классами.
🟠Легкость замены семейств продуктов: Можно легко менять фабрики, чтобы использовать другие семейства продуктов.
🟠Согласованность продуктов: Абстрактная фабрика гарантирует, что продукты одного семейства будут совместимы между собой.

🚩Недостатки абстрактной фабрики

🟠Усложнение кода: Добавление новых классов и интерфейсов может усложнить структуру кода.
🟠Трудности расширения: При добавлении нового типа продукта может потребоваться изменение интерфейсов и всех конкретных фабрик.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
🤔 Что такое паттерн Строитель (Builder)?

Паттерн "Строитель" — это порождающий паттерн проектирования, который позволяет создавать сложные объекты пошагово и отделяет процесс конструирования объекта от его представления, что дает возможность использовать один и тот же процесс для создания различных представлений.

🚩Основные концепции

🟠 Строитель (Builder): Интерфейс или абстрактный класс, определяющий шаги для построения объекта.
🟠Конкретные строители (Concrete Builders): Реализуют интерфейс строителя, создавая конкретные части продукта.
🟠Продукт (Product): Сложный объект, который строится.
🟠Директор (Director): Опциональный класс, который контролирует процесс построения, используя строителя.

🚩Пример использования паттерна для создания объектов типа House.

Создание продукта
class House:
def __init__(self):
self.walls = None
self.roof = None
self.windows = None

def __str__(self):
return f"House with {self.walls} walls, {self.roof} roof, and {self.windows} windows."


Определение интерфейса строителя
from abc import ABC, abstractmethod

class HouseBuilder(ABC):
@abstractmethod
def build_walls(self):
pass

@abstractmethod
def build_roof(self):
pass

@abstractmethod
def build_windows(self):
pass

@abstractmethod
def get_house(self):
pass


Создание конкретных строителей
class ConcreteHouseBuilder(HouseBuilder):
def __init__(self):
self.house = House()

def build_walls(self):
self.house.walls = "brick"
return self

def build_roof(self):
self.house.roof = "tile"
return self

def build_windows(self):
self.house.windows = "double-glazed"
return self

def get_house(self):
return self.house


Создание директора (опционально)
class Director:
def __init__(self, builder):
self.builder = builder

def construct_house(self):
self.builder.build_walls().build_roof().build_windows()
return self.builder.get_house()


Использование паттерна "Строитель"
# Использование без директора
builder = ConcreteHouseBuilder()
house = builder.build_walls().build_roof().build_windows().get_house()
print(house) # House with brick walls, tile roof, and double-glazed windows.

# Использование с директором
director = Director(builder)
house = director.construct_house()
print(house) # House with brick walls, tile roof, and double-glazed windows.


🚩Плюсы

🟠 Упрощение создания сложных объектов: Позволяет создавать сложные объекты пошагово.
🟠Отделение процесса конструирования от представления: Разделяет логику создания объекта и его состав.
🟠 Гибкость: Один и тот же процесс построения можно использовать для создания различных представлений объекта.

🚩Минусы

🟠Усложнение кода: Добавление дополнительных классов может усложнить структуру программы.
🟠Необходимость в дополнительных классах: Для каждого типа объекта требуется отдельный класс строителя.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103
🤔 Что такое Фабричный метод (Factory method)?

Это порождающий паттерн проектирования, который определяет интерфейс для создания объекта, но позволяет подклассам изменять тип создаваемого объекта. Это позволяет классу делегировать создание объектов подклассам, таким образом убирая жесткую привязку к конкретным классам и делая систему более гибкой и расширяемой.

🚩Основные концепции

🟠Продукт (Product): Определяет интерфейс для объектов, которые будут создаваться.
🟠Конкретный продукт (Concrete Product): Реализует интерфейс продукта.
🟠Создатель (Creator): Определяет фабричный метод, который возвращает объект продукта. Может содержать реализацию метода по умолчанию, возвращающую какой-то стандартный продукт.
🟠Конкретный создатель (Concrete Creator): Переопределяет фабричный метод для создания конкретного продукта.

🚩Использования фабричного метода

Определение интерфейса продукта
from abc import ABC, abstractmethod

class Animal(ABC):
@abstractmethod
def speak(self):
pass


Создание конкретных продуктов
class Dog(Animal):
def speak(self):
return "Woof!"

class Cat(Animal):
def speak(self):
return "Meow!"


Определение создателя
class AnimalFactory(ABC):
@abstractmethod
def create_animal(self) -> Animal:
pass

def some_operation(self) -> str:
animal = self.create_animal()
return f"The animal says: {animal.speak()}"


Создание конкретных создателей
class DogFactory(AnimalFactory):
def create_animal(self) -> Animal:
return Dog()

class CatFactory(AnimalFactory):
def create_animal(self) -> Animal:
return Cat()


Использование фабричного метода
def client_code(factory: AnimalFactory):
print(factory.some_operation())

dog_factory = DogFactory()
cat_factory = CatFactory()

print("Client: Testing client code with DogFactory:")
client_code(dog_factory) # Вывод: The animal says: Woof!

print("\nClient: Testing client code with CatFactory:")
client_code(cat_factory) # Вывод: The animal says: Meow!


🚩Плюсы

Изоляция конкретных классов: Клиентский код работает с интерфейсами или абстрактными классами, а не с конкретными реализациями.
Упрощение добавления новых продуктов: Легко добавлять новые виды продуктов, создавая новые конкретные создатели.
Гибкость и расширяемость: Позволяет изменять способ создания объектов без изменения клиентского кода.

🚩Минусы

Усложнение кода: Может потребоваться создание большого количества классов для каждого конкретного продукта и его создателя.
Дополнительные абстракции: Для каждого типа продукта требуется создание интерфейсов или абстрактных классов.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍2
🤔 Что такое паттерн Прототип (Prototype)?

Это порождающий паттерн проектирования, который позволяет создавать новые объекты, копируя уже существующие экземпляры. Этот паттерн полезен, когда процесс создания объекта является дорогим (в смысле затрат ресурсов) и трудоемким, а копирование существующего объекта оказывается проще и быстрее.

🚩Основные концепции

🟠Прототип (Prototype): Интерфейс или абстрактный класс, который объявляет метод clone(), позволяющий клонировать объект.
🟠Конкретный прототип (Concrete Prototype): Реализация интерфейса прототипа, которая определяет, как должен быть клонирован объект.
🟠Клиент (Client): Объект, который создает новые объекты, вызывая метод clone() на прототипах.

🚩Плюсы

Скорость создания объектов: Клонирование объектов может быть быстрее, чем создание новых с нуля, особенно если процесс создания объектов сложен.
Уменьшение зависимости от конкретных классов: Клиенты могут работать с интерфейсом прототипа вместо работы с конкретными классами.
Упрощение добавления и удаления объектов: Легко создавать новые типы объектов путем клонирования существующих.

🚩Минусы

Сложность реализации: Реализация клонирования может быть сложной, особенно если объект имеет сложные зависимости или использует ресурсы, которые не могут быть просто скопированы.
Проблемы с глубоким и поверхностным копированием: Нужно тщательно продумать, как должны копироваться вложенные объекты (глубокое копирование или поверхностное копирование).

🚩Пример

Определение интерфейса прототипа
from abc import ABC, abstractmethod
import copy

class Shape(ABC):
def __init__(self, id):
self.id = id

@abstractmethod
def clone(self):
pass


Создание конкретных прототипов
class Rectangle(Shape):
def __init__(self, id, width, height):
super().__init__(id)
self.width = width
self.height = height

def clone(self):
return copy.deepcopy(self)

def __str__(self):
return f"Rectangle(id={self.id}, width={self.width}, height={self.height})"

class Circle(Shape):
def __init__(self, id, radius):
super().__init__(id)
self.radius = radius

def clone(self):
return copy.deepcopy(self)

def __str__(self):
return f"Circle(id={self.id}, radius={self.radius})"


Использование прототипа
def main():
rect1 = Rectangle(1, 10, 20)
circle1 = Circle(2, 15)

rect2 = rect1.clone()
circle2 = circle1.clone()

print(rect1) # Rectangle(id=1, width=10, height=20)
print(rect2) # Rectangle(id=1, width=10, height=20)
print(circle1) # Circle(id=2, radius=15)
print(circle2) # Circle(id=2, radius=15)

if __name__ == "__main__":
main()


Ставь
👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Что такое Структурные (Structural) паттерны?

Это паттерны проектирования, которые упрощают создание отношений между объектами, обеспечивая гибкую структуру и способствуя повторному использованию кода. Эти паттерны помогают организовать классы и объекты в большие структуры, сохраняя при этом гибкость и эффективность.

🚩Описание и примеры

🟠Адаптер (Adapter)
Паттерн Адаптер позволяет объектам с несовместимыми интерфейсами работать вместе. Он оборачивает один из объектов, преобразуя его интерфейс в совместимый.
class EuropeanSocket:
def voltage(self):
return 230

class USASocket:
def voltage(self):
return 120

class Adapter:
def __init__(self, socket):
self.socket = socket

def voltage(self):
return self.socket.voltage()

# Использование
european_socket = EuropeanSocket()
adapter = Adapter(european_socket)
print(adapter.voltage()) # 230


🟠Мост (Bridge)
Паттерн Мост разделяет абстракцию и реализацию, позволяя изменять их независимо друг от друга.
class DrawingAPI:
def draw_circle(self, x, y, radius):
pass

class DrawingAPI1(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API1.circle at {x}:{y} radius {radius}")

class DrawingAPI2(DrawingAPI):
def draw_circle(self, x, y, radius):
print(f"API2.circle at {x}:{y} radius {radius}")

class Shape:
def __init__(self, drawing_api):
self.drawing_api = drawing_api

def draw(self):
pass

class CircleShape(Shape):
def __init__(self, x, y, radius, drawing_api):
super().__init__(drawing_api)
self.x = x
self.y = y
self.radius = radius

def draw(self):
self.drawing_api.draw_circle(self.x, self.y, self.radius)

# Использование
circle1 = CircleShape(1, 2, 3, DrawingAPI1())
circle2 = CircleShape(5, 7, 11, DrawingAPI2())
circle1.draw() # API1.circle at 1:2 radius 3
circle2.draw() # API2.circle at 5:7 radius 11


🟠Компоновщик (Composite)
Паттерн Компоновщик позволяет группировать объекты в древовидные структуры для представления иерархий "часть-целое".
class Component:
def operation(self):
pass

class Leaf(Component):
def operation(self):
return "Leaf"

class Composite(Component):
def __init__(self):
self.children = []

def add(self, component):
self.children.append(component)

def operation(self):
results = []
for child in self.children:
results.append(child.operation())
return f"Branch({'+'.join(results)})"

# Использование
leaf1 = Leaf()
leaf2 = Leaf()
composite = Composite()
composite.add(leaf1)
composite.add(leaf2)
print(composite.operation()) # Branch(Leaf+Leaf)


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5