А расскажите о паттернах программирования в пайтоне?
Паттерны программирования (или шаблоны проектирования) — это проверенные решения типичных задач, возникающих при разработке программного обеспечения. Они помогают структурировать код, делая его более читаемым, поддерживаемым и масштабируемым. В Python, как и в других языках, используются классические паттерны, описанные в книге «Банды четырёх» (Gang of Four, GoF), а также специфические для Python подходы.
### Основные категории паттернов
1. **Порождающие паттерны** — отвечают за создание объектов.
2. **Структурные паттерны** — помогают организовать структуру классов и объектов.
3. **Поведенческие паттерны** — определяют взаимодействие между объектами.
---
### Порождающие паттерны
1. **Singleton (Одиночка)**
Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему.
```python
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # True
```
2. **Factory Method (Фабричный метод)**
Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.
```python
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self) -> str:
pass
class ConcreteProductA(Product):
def operation(self) -> str:
return "Product A"
class Creator(ABC):
@abstractmethod
def factory_method(self) -> Product:
pass
def some_operation(self) -> str:
product = self.factory_method()
return f"Creator: {product.operation()}"
class ConcreteCreatorA(Creator):
def factory_method(self) -> Product:
return ConcreteProductA()
creator = ConcreteCreatorA()
print(creator.some_operation()) # Creator: Product A
```
3. **Builder (Строитель)**
Позволяет создавать сложные объекты пошагово.
```python
class Pizza:
def __init__(self):
self.toppings = []
def add_topping(self, topping):
self.toppings.append(topping)
def __str__(self):
return f"Pizza with {', '.join(self.toppings)}"
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def add_pepperoni(self):
self.pizza.add_topping("pepperoni")
return self
def add_mushrooms(self):
self.pizza.add_topping("mushrooms")
return self
def build(self):
return self.pizza
pizza = PizzaBuilder().add_pepperoni().add_mushrooms().build()
print(pizza) # Pizza with pepperoni, mushrooms
```
---
### Структурные паттерны
1. **Adapter (Адаптер)**
Позволяет объектам с несовместимыми интерфейсами работать вместе.
```python
class OldSystem:
def old_operation(self):
return "Old System"
class Adapter:
def __init__(self, old_system):
self.old_system = old_system
def new_operation(self):
return f"Adapter: {self.old_system.old_operation()}"
old_system = OldSystem()
adapter = Adapter(old_system)
print(adapter.new_operation()) # Adapter: Old System
```
2. **Decorator (Декоратор)**
Динамически добавляет объекту новые обязанности.
```python
class Component:
def operation(self) -> str:
return "Component"
class Decorator(Component):
def __init__(self, component: Component):
self._component = component
def operation(self) -> str:
return f"Decorator({self._component.operation()})"
component = Component()
decorated = Decorator(component)
print(decorated.operation()) # Decorator(Component)
```
3. **Facade (Фасад)**
Предоставляет простой интерфейс для сложной системы.
```python
class SubsystemA:
def operation_a(self):
return "Subsystem A"
class SubsystemB:
def operation_b(self):
return "Subsystem B"
class Facade:
def __init__(self):
self._subsystem_a = SubsystemA()
self._subsystem_b = SubsystemB()
def operation(self):
return f"{self._subsystem_a.operation_a()}, {self._subsystem_b.operation_b()}"
facade = Facade()
print(facade.operation()) # Subsystem A, Subsystem B
```
---
### Поведенческие паттерны
1. **Observer (Наблюдатель)**
Определяет зависимость «один ко многим» между объектами, чтобы при изменении состояния одного объекта все зависящие от него объекты уведомлялись.
```python
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
class Observer:
def update(self, subject):
pass
class ConcreteObserver(Observer):
def update(self, subject):
print("Subject state changed!")
subject = Subject()
observer = ConcreteObserver()
subject.attach(observer)
subject.notify() # Subject state changed!
```
2. **Strategy (Стратегия)**
Позволяет выбирать алгоритм во время выполнения программы.
```python
from abc import ABC, abstractmethod
class Strategy(ABC):
@abstractmethod
def execute(self, data):
pass
class StrategyA(Strategy):
def execute(self, data):
return sorted(data)
class StrategyB(Strategy):
def execute(self, data):
return sorted(data, reverse=True)
class Context:
def __init__(self, strategy: Strategy):
self._strategy = strategy
def execute_strategy(self, data):
return self._strategy.execute(data)
data = [3, 1, 4, 1, 5]
context = Context(StrategyA())
print(context.execute_strategy(data)) # [1, 1, 3, 4, 5]
```
3. **Command (Команда)**
Инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами.
```python
class Command:
def execute(self):
pass
class LightOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.on()
class Light:
def on(self):
print("Light is on")
light = Light()
command = LightOnCommand(light)
command.execute() # Light is on
```
---
### Специфические для Python подходы
1. **Использование декораторов функций**
В Python декораторы часто используются для добавления функциональности к функциям.
```python
def my_decorator(func):
def wrapper():
print("Something before the function.")
func()
print("Something after the function.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function.
# Hello!
# Something after the function.
```
2. **Использование контекстных менеджеров**
Контекстные менеджеры (`with`) упрощают управление ресурсами.
```python
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with FileManager("test.txt", "w") as f:
f.write("Hello, World!")
```
Паттерны программирования в Python помогают писать более структурированный и поддерживаемый код, но важно использовать их с умом, чтобы не усложнять проект без необходимости.
Я тащусь от этого пульсара...блин мазаный
### Основные категории паттернов
1. **Порождающие паттерны** — отвечают за создание объектов.
2. **Структурные паттерны** — помогают организовать структуру классов и объектов.
3. **Поведенческие паттерны** — определяют взаимодействие между объектами.
---
### Порождающие паттерны
1. **Singleton (Одиночка)**
Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему.
```python
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # True
```
2. **Factory Method (Фабричный метод)**
Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, какой класс инстанцировать.
```python
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self) -> str:
pass
class ConcreteProductA(Product):
def operation(self) -> str:
return "Product A"
class Creator(ABC):
@abstractmethod
def factory_method(self) -> Product:
pass
def some_operation(self) -> str:
product = self.factory_method()
return f"Creator: {product.operation()}"
class ConcreteCreatorA(Creator):
def factory_method(self) -> Product:
return ConcreteProductA()
creator = ConcreteCreatorA()
print(creator.some_operation()) # Creator: Product A
```
3. **Builder (Строитель)**
Позволяет создавать сложные объекты пошагово.
```python
class Pizza:
def __init__(self):
self.toppings = []
def add_topping(self, topping):
self.toppings.append(topping)
def __str__(self):
return f"Pizza with {', '.join(self.toppings)}"
class PizzaBuilder:
def __init__(self):
self.pizza = Pizza()
def add_pepperoni(self):
self.pizza.add_topping("pepperoni")
return self
def add_mushrooms(self):
self.pizza.add_topping("mushrooms")
return self
def build(self):
return self.pizza
pizza = PizzaBuilder().add_pepperoni().add_mushrooms().build()
print(pizza) # Pizza with pepperoni, mushrooms
```
---
### Структурные паттерны
1. **Adapter (Адаптер)**
Позволяет объектам с несовместимыми интерфейсами работать вместе.
```python
class OldSystem:
def old_operation(self):
return "Old System"
class Adapter:
def __init__(self, old_system):
self.old_system = old_system
def new_operation(self):
return f"Adapter: {self.old_system.old_operation()}"
old_system = OldSystem()
adapter = Adapter(old_system)
print(adapter.new_operation()) # Adapter: Old System
```
2. **Decorator (Декоратор)**
Динамически добавляет объекту новые обязанности.
```python
class Component:
def operation(self) -> str:
return "Component"
class Decorator(Component):
def __init__(self, component: Component):
self._component = component
def operation(self) -> str:
return f"Decorator({self._component.operation()})"
component = Component()
decorated = Decorator(component)
print(decorated.operation()) # Decorator(Component)
```
3. **Facade (Фасад)**
Предоставляет простой интерфейс для сложной системы.
```python
class SubsystemA:
def operation_a(self):
return "Subsystem A"
class SubsystemB:
def operation_b(self):
return "Subsystem B"
class Facade:
def __init__(self):
self._subsystem_a = SubsystemA()
self._subsystem_b = SubsystemB()
def operation(self):
return f"{self._subsystem_a.operation_a()}, {self._subsystem_b.operation_b()}"
facade = Facade()
print(facade.operation()) # Subsystem A, Subsystem B
```
---
### Поведенческие паттерны
1. **Observer (Наблюдатель)**
Определяет зависимость «один ко многим» между объектами, чтобы при изменении состояния одного объекта все зависящие от него объекты уведомлялись.
```python
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def notify(self):
for observer in self._observers:
observer.update(self)
class Observer:
def update(self, subject):
pass
class ConcreteObserver(Observer):
def update(self, subject):
print("Subject state changed!")
subject = Subject()
observer = ConcreteObserver()
subject.attach(observer)
subject.notify() # Subject state changed!
```
2. **Strategy (Стратегия)**
Позволяет выбирать алгоритм во время выполнения программы.
```python
from abc import ABC, abstractmethod
class Strategy(ABC):
@abstractmethod
def execute(self, data):
pass
class StrategyA(Strategy):
def execute(self, data):
return sorted(data)
class StrategyB(Strategy):
def execute(self, data):
return sorted(data, reverse=True)
class Context:
def __init__(self, strategy: Strategy):
self._strategy = strategy
def execute_strategy(self, data):
return self._strategy.execute(data)
data = [3, 1, 4, 1, 5]
context = Context(StrategyA())
print(context.execute_strategy(data)) # [1, 1, 3, 4, 5]
```
3. **Command (Команда)**
Инкапсулирует запрос как объект, позволяя параметризовать клиентов с различными запросами.
```python
class Command:
def execute(self):
pass
class LightOnCommand(Command):
def __init__(self, light):
self.light = light
def execute(self):
self.light.on()
class Light:
def on(self):
print("Light is on")
light = Light()
command = LightOnCommand(light)
command.execute() # Light is on
```
---
### Специфические для Python подходы
1. **Использование декораторов функций**
В Python декораторы часто используются для добавления функциональности к функциям.
```python
def my_decorator(func):
def wrapper():
print("Something before the function.")
func()
print("Something after the function.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
# Output:
# Something before the function.
# Hello!
# Something after the function.
```
2. **Использование контекстных менеджеров**
Контекстные менеджеры (`with`) упрощают управление ресурсами.
```python
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with FileManager("test.txt", "w") as f:
f.write("Hello, World!")
```
Паттерны программирования в Python помогают писать более структурированный и поддерживаемый код, но важно использовать их с умом, чтобы не усложнять проект без необходимости.
Я тащусь от этого пульсара...блин мазаный
Результатов не найдено
Приглашен:
Чтобы ответить на вопросы, пожалуйста, сначала войдите или зарегистрируйтесь
7 ответов
Pimidorca - Участник (843)
Нравитcя: AveDeo , Капля_Никотина , Piligrim , Тристаграмм , Evg , ИнгаБольше »
potap - Старожил (42308)
Нравитcя: AveDeo , Piligrim , Капля_Никотина , Evg
Marsel - Dum spiro – spero! - Старожил (116196)
Нравитcя: Тристаграмм , Domenik , Evg , Solomeya
Капля_Никотина - https://www.youtube.com/watch?v=0_BB3B0b4iA - Старожил (33860)
Нравитcя: AveDeo , potap , Evg
Piligrim - Исчезающий вид - Старожил (116161)
Нравитcя: AveDeo , Evg , Инга
Knight_Rider - Завсегдатай (3910)
Нравитcя: AveDeo
Тристаграмм - Участник (353)