Python | Вопросы собесов
13.8K subscribers
38 photos
1 file
959 links
Download Telegram
🤔 Что такое паттерн Интерпретатор (Interpreter)?

Паттерн Интерпретатор (Interpreter) — это поведенческий паттерн проектирования, который определяет грамматику для представления языка и интерпретатор, использующий эту грамматику для интерпретации предложений на этом языке. Паттерн используется для построения простых языков или для интерпретации конкретного типа выражений.

🚩Зачем нужен?

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

🚩Пример

from abc import ABC, abstractmethod

# Интерфейс выражения
class Expression(ABC):
@abstractmethod
def interpret(self):
pass

# Конкретное выражение для чисел
class Number(Expression):
def __init__(self, value):
self.value = value

def interpret(self):
return self.value

# Конкретное выражение для сложения
class Add(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right

def interpret(self):
return self.left.interpret() + self.right.interpret()

# Конкретное выражение для умножения
class Multiply(Expression):
def __init__(self, left: Expression, right: Expression):
self.left = left
self.right = right

def interpret(self):
return self.left.interpret() * self.right.interpret()

# Клиентский код для использования паттерна Интерпретатор
def main():
# Создаем выражение: (5 + 10) * 2
expression = Multiply(
Add(Number(5), Number(10)),
Number(2)
)

result = expression.interpret()
print(f"Result: {result}") # Result: 30

if __name__ == "__main__":
main()


1⃣Интерфейс `Expression`:
Объявляет метод interpret, который должен реализовать каждое конкретное выражение.
2⃣Конкретные выражения:
Классы Number, Add и Multiply, которые реализуют интерфейс Expression и определяют интерпретацию чисел, сложения и умножения соответственно.
3⃣Компоновка выражений:
Выражения могут быть составными, например, Add и Multiply могут принимать другие выражения в качестве аргументов.
4⃣Интерпретация:
Метод interpret вызывается для вычисления значения выражения.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍81
🤔 Какие есть типы данных в Python?

В Python существует несколько встроенных типов данных: числовые типы (int, float, complex), строки (str), булевы значения (bool), списки (list), кортежи (tuple), множества (set) и словари (dict). Также есть типы для работы с бинарными данными, такие как bytes и bytearray. Кроме того, существуют пользовательские типы, которые можно создавать с помощью классов. Python поддерживает динамическую типизацию, где тип переменной определяется автоматически при присваивании значения.

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

Паттерн "Мост" (Bridge) является структурным паттерном проектирования, который предназначен для разделения абстракции и реализации так, чтобы они могли изменяться независимо друг от друга. Этот паттерн полезен, когда класс должен работать с различными платформами или когда нужно избежать жесткой связки между абстракцией и ее реализацией.

🚩 Зачем нужен

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

🚩Как используется

🟠Абстракция (Abstraction):
Определяет интерфейс и хранит ссылку на объект Implementor.
🟠Расширенная абстракция (RefinedAbstraction):
Наследует Abstraction и расширяет интерфейс.
🟠Реализатор (Implementor):
Определяет интерфейс для всех реализаций.
🟠Конкретный реализатор (ConcreteImplementor):
Реализует интерфейс Implementor.

Допустим, у нас есть программа для управления различными типами устройств (например, телевизор и радио), которые можно включать и выключать. Мы хотим, чтобы способ управления устройствами мог изменяться независимо от типов устройств.
# Implementor
class Device:
def is_enabled(self):
pass

def enable(self):
pass

def disable(self):
pass

# ConcreteImplementor
class TV(Device):
def __init__(self):
self._on = False

def is_enabled(self):
return self._on

def enable(self):
self._on = True

def disable(self):
self._on = False

class Radio(Device):
def __init__(self):
self._on = False

def is_enabled(self):
return self._on

def enable(self):
self._on = True

def disable(self):
self._on = False

# Abstraction
class RemoteControl:
def __init__(self, device):
self._device = device

def toggle_power(self):
if self._device.is_enabled():
self._device.disable()
else:
self._device.enable()

# RefinedAbstraction
class AdvancedRemoteControl(RemoteControl):
def mute(self):
print("Device is muted.")

# Клиентский код
tv = TV()
remote = RemoteControl(tv)
remote.toggle_power() # Включает TV

radio = Radio()
advanced_remote = AdvancedRemoteControl(radio)
advanced_remote.toggle_power() # Включает Radio
advanced_remote.mute() # Заглушает Radio


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

Контекстный менеджер в Python — это конструкция, которая управляет ресурсами и обеспечивает выполнение определенных действий до и после использования ресурса. Чаще всего используется с оператором `with`, чтобы гарантировать корректное открытие и закрытие ресурсов, таких как файлы или сетевые соединения. В классе контекстного менеджера должны быть реализованы методы `__enter__()` и `__exit__()`. Этот механизм помогает избежать ошибок, связанных с неправильным управлением ресурсами.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай
📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥92
🤔 Что такое паттерн Компоновщик (Composite)?

Паттерн Компоновщик (Composite) — это структурный паттерн проектирования, который позволяет сгруппировать объекты в древовидную структуру для представления иерархии "часть-целое". Этот паттерн используется для работы с объектами как с единичными, так и с составными единицами, предоставляя единый интерфейс для работы с ними.

🚩Зачем нужен?

Основная цель паттерна Компоновщик — упростить работу с иерархическими структурами данных. Он позволяет клиенту обращаться с отдельными объектами и их группами единообразно, что делает код более гибким и упрощает его поддержку.

🚩Как используется паттерн Компоновщик?

🟠Лист (Leaf):
это базовый элемент без подкомпонентов.
🟠Компоновщик (Composite):
это элемент, который может содержать другие компоненты, включая и листья, и другие компоновщики.
from abc import ABC, abstractmethod

# Абстрактный компонент
class Graphic(ABC):
@abstractmethod
def draw(self):
pass

# Лист
class Circle(Graphic):
def draw(self):
print("Drawing a Circle")

# Компоновщик
class CompositeGraphic(Graphic):
def __init__(self):
self.graphics = []

def add(self, graphic):
self.graphics.append(graphic)

def remove(self, graphic):
self.graphics.remove(graphic)

def draw(self):
for graphic in self.graphics:
graphic.draw()

# Клиентский код
circle1 = Circle()
circle2 = Circle()
composite = CompositeGraphic()
composite.add(circle1)
composite.add(circle2)

# Рисуем все элементы
composite.draw()


🚩Плюсы

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

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 В чем разница между итератором и генератором?

Итератор — это объект, который поддерживает метод `__iter__()` и `__next__()` и позволяет проходить по коллекции элементов. Генератор — это специальный вид итератора, который создается с помощью ключевого слова `yield` и позволяет лениво возвращать элементы по одному, сохраняя состояние между вызовами. Генераторы обычно используются для обработки больших данных, поскольку они не требуют загрузки всего набора данных в память. Итераторы, в свою очередь, могут быть созданы вручную с помощью классов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍101
🤔 Что такое паттерн Фасад (Facade)?

Паттерн Фасад (Facade) — это структурный паттерн проектирования, который предоставляет упрощённый интерфейс к сложной системе классов, библиотеке или фреймворку. Основная цель паттерна — уменьшить сложность взаимодействия с системой, скрывая её внутренние детали и предоставляя более простой интерфейс для клиента.

🚩Зачем нужен?

Фасад помогает уменьшить сложность больших систем, делая их более понятными и удобными для использования. Он позволяет отделить клиентов системы от её сложных внутренних деталей, что облегчает поддержку и расширение системы.

🚩Как используется?

Фасад создаётся как класс, который инкапсулирует взаимодействие с одной или несколькими подсистемами. Клиенты обращаются к этому фасаду, чтобы выполнять нужные действия, не вдаваясь в детали реализации этих действий.
# Подсистема 1
class CPU:
def freeze(self):
print("CPU freezing")

def jump(self, position):
print(f"CPU jumping to {position}")

def execute(self):
print("CPU executing")

# Подсистема 2
class Memory:
def load(self, position, data):
print(f"Memory loading {data} at {position}")

# Подсистема 3
class HardDrive:
def read(self, lba, size):
return f"Reading {size} bytes from LBA {lba}"

# Фасад
class ComputerFacade:
def __init__(self):
self.cpu = CPU()
self.memory = Memory()
self.hard_drive = HardDrive()

def start(self):
self.cpu.freeze()
self.memory.load("0x00", self.hard_drive.read("100", "1024"))
self.cpu.jump("0x00")
self.cpu.execute()

# Клиентский код
computer = ComputerFacade()
computer.start()


🚩Плюсы

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

🚩Минусы

Ограниченная функциональность: Может возникнуть ситуация, когда фасад не предоставляет весь необходимый функционал, требующийся клиенту.
Дополнительный слой абстракции: Создание фасада добавляет ещё один уровень абстракции, что может слегка усложнить систему.

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

SOLID — это пять принципов объектно-ориентированного программирования, которые помогают проектировать гибкие, расширяемые и поддерживаемые системы. Они включают в себя: Single Responsibility (одна ответственность), Open/Closed (открытость для расширения, закрытость для изменений), Liskov Substitution (замена по Лисков), Interface Segregation (разделение интерфейсов) и Dependency Inversion (инверсия зависимостей). Эти принципы улучшают архитектуру программного обеспечения и делают код более надежным.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍9
🤔 Что такое хранитель (Memento)?

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

🚩Зачем нужен?

🟠Сохранение состояния:
Позволяет сохранять текущее состояние объекта и восстанавливать его позже.
🟠Инкапсуляция:
Обеспечивает сохранение состояния объекта без нарушения его инкапсуляции. Внутренние детали объекта остаются скрытыми от других объектов.
🟠Отмена и повтор операций:
Поддерживает функциональность отмены и повтора операций, так как позволяет возвращать объект к предыдущим состояниям.
Пример реализации
class Memento:
def __init__(self, state: str):
self._state = state

def get_state(self) -> str:
return self._state

class TextEditor:
def __init__(self):
self._state = ""
self._history = []

def type(self, text: str):
self._save_state()
self._state += text

def _save_state(self):
self._history.append(Memento(self._state))

def undo(self):
if not self._history:
return
memento = self._history.pop()
self._state = memento.get_state()

def get_content(self) -> str:
return self._state

# Клиентский код для использования паттерна Хранитель
def main():
editor = TextEditor()

editor.type("Hello, ")
editor.type("world!")
print(editor.get_content()) # Hello, world!

editor.undo()
print(editor.get_content()) # Hello,

editor.undo()
print(editor.get_content()) #

if __name__ == "__main__":
main()


1⃣`Memento`:
Сохраняет состояние объекта. Он предоставляет методы для получения сохраненного состояния, но не предоставляет методов для изменения состояния, что обеспечивает неизменность.

2⃣`TextEditor`:
Создает и использует объекты Memento для сохранения и восстановления своего состояния. Методы type и undo позволяют редактировать текст и отменять изменения.

3⃣`_save_state`:
Сохраняет текущее состояние редактора в истории перед каждым изменением.

4⃣`undo`:
Восстанавливает предыдущее состояние редактора из истории.

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

Декораторы в Python — это функции, которые принимают другую функцию или метод в качестве аргумента и изменяют или расширяют её поведение. Они позволяют легко добавлять функциональность без изменения исходного кода функции. Декораторы применяются с помощью символа `@` перед определением функции. Это мощный механизм для рефакторинга, добавления логгирования, проверки прав доступа и других задач.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26🔥8💊3
🤔 Что такое Наблюдатель (Observer)?

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

🚩Зачем нужен?

🟠Разделение обязанностей:
Позволяет отделить объект, который изменяет свое состояние, от объектов, которые реагируют на эти изменения.
🟠Поддержка реактивного программирования:
Обеспечивает автоматическое уведомление и обновление зависимых объектов при изменении состояния наблюдаемого объекта.
🟠Гибкость и расширяемость:
Легко добавлять или удалять наблюдателей без изменения кода наблюдаемого объекта.
Пример реализации
from abc import ABC, abstractmethod

class Observer(ABC):
@abstractmethod
def update(self, message: str):
pass

class ConcreteObserver(Observer):
def __init__(self, name: str):
self._name = name

def update(self, message: str):
print(f"{self._name} received message: {message}")

class Subject:
def __init__(self):
self._observers = []

def add_observer(self, observer: Observer):
self._observers.append(observer)

def remove_observer(self, observer: Observer):
self._observers.remove(observer)

def notify_observers(self, message: str):
for observer in self._observers:
observer.update(message)

# Клиентский код для использования паттерна Наблюдатель
def main():
subject = Subject()

observer1 = ConcreteObserver("Observer 1")
observer2 = ConcreteObserver("Observer 2")

subject.add_observer(observer1)
subject.add_observer(observer2)

subject.notify_observers("Event 1") # Observer 1 received message: Event 1
# Observer 2 received message: Event 1

subject.remove_observer(observer1)

subject.notify_observers("Event 2") # Observer 2 received message: Event 2

if __name__ == "__main__":
main()


1⃣`Observer`:
Объявляет метод update, который должны реализовать все конкретные наблюдатели.
2⃣`ConcreteObserver`:
Реализует интерфейс Observer и определяет, как наблюдатель должен реагировать на обновления.
3⃣`Subject`:
Содержит список наблюдателей и методы для добавления, удаления и уведомления наблюдателей.
4⃣`notify_observers`:
Вызывается при изменении состояния субъекта и уведомляет всех зарегистрированных наблюдателей.

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

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥7💊21
🤔 Что такое паттерн Состояние (State)?

Это поведенческий паттерн проектирования, который позволяет объекту изменять свое поведение в зависимости от его состояния. Это делается путем инкапсуляции состояний в отдельные классы и делегирования задач состояниям, таким образом объект изменяет свой класс поведения при изменении состояния.

🚩Зачем нужен

🟠Управление сложными переходами
🟠Инкапсуляция логики состояния
Логика, связанная с конкретными состояниями, инкапсулируется в отдельных классах, что способствует лучшему разделению обязанностей и поддержке кода.
🟠Гибкость и расширяемость
Легко добавлять новые состояния и изменять существующие без внесения изменений в основной код объекта.
from abc import ABC, abstractmethod

# Интерфейс состояния
class State(ABC):
@abstractmethod
def insert_coin(self):
pass

@abstractmethod
def eject_coin(self):
pass

@abstractmethod
def dispense(self):
pass

# Конкретные состояния
class NoCoinState(State):
def __init__(self, machine):
self.machine = machine

def insert_coin(self):
print("Coin inserted.")
self.machine.set_state(self.machine.has_coin_state)

def eject_coin(self):
print("No coin to eject.")

def dispense(self):
print("Insert coin first.")

class HasCoinState(State):
def __init__(self, machine):
self.machine = machine

def insert_coin(self):
print("Coin already inserted.")

def eject_coin(self):
print("Coin ejected.")
self.machine.set_state(self.machine.no_coin_state)

def dispense(self):
print("Dispensing product.")
self.machine.set_state(self.machine.no_coin_state)

# Контекст
class VendingMachine:
def __init__(self):
self.no_coin_state = NoCoinState(self)
self.has_coin_state = HasCoinState(self)
self.state = self.no_coin_state

def set_state(self, state: State):
self.state = state

def insert_coin(self):
self.state.insert_coin()

def eject_coin(self):
self.state.eject_coin()

def dispense(self):
self.state.dispense()

# Клиентский код
def main():
machine = VendingMachine()

machine.insert_coin() # Coin inserted.
machine.dispense() # Dispensing product.
machine.eject_coin() # No coin to eject.

machine.insert_coin() # Coin inserted.
machine.eject_coin() # Coin ejected.
machine.dispense() # Insert coin first.

if __name__ == "__main__":
main()


🚩Как это работает

🟠Интерфейс `State`
Определяет методы, которые должны реализовать все конкретные состояния.
🟠Конкретные состояния (`NoCoinState`, `HasCoinState`)
Реализуют интерфейс State и определяют поведение для каждого состояния.
🟠Класс `VendingMachine`
Содержит ссылки на все возможные состояния и метод для изменения текущего состояния. Делегирует вызовы методов текущему состоянию.
🟠Методы `insert_coin`, `eject_coin`, `dispense`
Вызываются клиентом и делегируются текущему состоянию.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🤔 Чем init() отличается от new()?

Метод `__init__()` отвечает за инициализацию объекта после его создания и не создает сам объект, а лишь настраивает его начальные параметры. Метод `__new__()` отвечает за создание нового экземпляра класса и вызывается перед `__init__()`. `__new__()` используется, когда требуется контролировать процесс создания объектов, например, при наследовании или работе с неизменяемыми типами. В большинстве случаев программисту достаточно использовать только `__init__()`.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🔥10
🤔 Что такое RPC?

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

🚩Зачем нужен?

🟠Простота использования
Позволяет разработчикам вызывать удаленные процедуры так, как будто они находятся на локальной машине, что упрощает программирование распределенных систем.
🟠Абстракция сетевого взаимодействия
Скрывает сложность сетевого взаимодействия, позволяя сосредоточиться на логике приложения.
🟠Интероперабельность
Обеспечивает взаимодействие между приложениями, работающими на разных платформах и написанных на разных языках программирования.

🚩Как работает

1⃣Клиент
Инициирует вызов удаленной процедуры, отправляя запрос на сервер.
2⃣Сервер
Принимает запрос, выполняет запрашиваемую процедуру и возвращает результат клиенту.

Сервер
from xmlrpc.server import SimpleXMLRPCServer

def add(x, y):
return x + y

def main():
server = SimpleXMLRPCServer(("localhost", 8000))
print("Listening on port 8000...")
server.register_function(add, "add")
server.serve_forever()

if __name__ == "__main__":
main()


3⃣Stub (заглушки)
Клиентские и серверные заглушки генерируются для сериализации и десериализации данных, что позволяет передавать данные по сети.

Клиент
import xmlrpc.client

def main():
with xmlrpc.client.ServerProxy("https://localhost:8000/") as proxy:
result = proxy.add(5, 3)
print(f"5 + 3 = {result}")

if __name__ == "__main__":
main()


🚩Как это работает

1⃣Сервер
Создает XML-RPC сервер и регистрирует функцию add, которая принимает два числа и возвращает их сумму. Сервер ожидает запросы на порту 8000.
2⃣Клиент
Подключается к серверу через ServerProxy и вызывает удаленную функцию add с аргументами 5 и 3. Результат вызова выводится на экран.

🚩Плюсы

Упрощение распределенного программирования
Обеспечивает простой интерфейс для вызова удаленных процедур.
Повышение производительности
Меньше задержек по сравнению с передачей сообщений благодаря синхронным вызовам.
Интероперабельность
Поддерживает взаимодействие между системами на разных платформах и языках программирования.

🚩Минусы

Зависимость от сети
Работа системы зависит от сетевого соединения, что может приводить к задержкам и ошибкам.
Сложность отладки
Ошибки и проблемы могут быть сложными для диагностики из-за распределенной природы системы.
Безопасность
Необходимо обеспечить безопасность данных, передаваемых по сети, особенно при использовании в открытых сетях.

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

Итератор в Python — это объект, который поддерживает метод `__iter__()` и `__next__()` для последовательного перебора элементов коллекции. Итераторы используются для работы с циклами и обеспечивают ленивую генерацию данных, не загружая их все сразу в память. Каждый вызов метода `next()` возвращает следующий элемент, а при отсутствии элементов вызывается исключение `StopIteration`. Итераторы полезны для работы с большими данными и потоками данных.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4💊1
🤔 Что такое lru cache?

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

🚩Зачем нужен?

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

Python предоставляет удобную реализацию LRU-кэша через декоратор lru_cache в модуле functools. Этот декоратор можно использовать для кэширования результатов вызова функции.
from functools import lru_cache

@lru_cache(maxsize=4)
def expensive_computation(n):
print(f"Computing {n}...")
return n * n

def main():
print(expensive_computation(1)) # Computing 1... -> 1
print(expensive_computation(2)) # Computing 2... -> 4
print(expensive_computation(3)) # Computing 3... -> 9
print(expensive_computation(4)) # Computing 4... -> 16

print(expensive_computation(1)) # Cached -> 1
print(expensive_computation(2)) # Cached -> 4

print(expensive_computation(5)) # Computing 5... -> 25 (1 removed from cache)
print(expensive_computation(3)) # Cached -> 9

print(expensive_computation(1)) # Computing 1... -> 1 (2 removed from cache)

if __name__ == "__main__":
main()


1⃣Декоратор `@lru_cache`
Декорирует функцию expensive_computation, добавляя механизм кэширования.

2⃣Аргумент `maxsize`
Определяет максимальный размер кэша. В данном примере, кэш может хранить до 4 элементов.

3⃣Кэширование и замена
При вызове функции сначала проверяется, есть ли результат в кэше. Если есть, возвращается кэшированный результат. Если нет, функция вычисляет результат, и он сохраняется в кэш. Когда кэш переполняется, наименее недавно использованный элемент удаляется.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
🤔 Какие знаешь принципы ООП?

Основные принципы ООП включают инкапсуляцию, наследование, полиморфизм и абстракцию. Инкапсуляция скрывает внутренние детали реализации и защищает данные, предоставляя доступ через методы. Наследование позволяет создавать новые классы на основе существующих, а полиморфизм позволяет использовать один и тот же интерфейс для объектов разных классов. Абстракция упрощает сложные системы, скрывая ненужные детали и выделяя ключевые характеристики.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥5💊1
🤔 Что такое шаблонный метод (Template method)?

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

🚩Зачем нужен?

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

🚩Пример использования

Пример реализации паттерна Шаблонный метод для процесса приготовления кофе и чая. Общие шаги включают кипячение воды, заваривание напитка и добавление добавок, но конкретные шаги зависят от типа напитка.
from abc import ABC, abstractmethod

class CaffeineBeverage(ABC):
def prepare_recipe(self):
self.boil_water()
self.brew()
self.pour_in_cup()
self.add_condiments()

def boil_water(self):
print("Boiling water")

def pour_in_cup(self):
print("Pouring into cup")

@abstractmethod
def brew(self):
pass

@abstractmethod
def add_condiments(self):
pass

class Tea(CaffeineBeverage):
def brew(self):
print("Steeping the tea")

def add_condiments(self):
print("Adding lemon")

class Coffee(CaffeineBeverage):
def brew(self):
print("Dripping coffee through filter")

def add_condiments(self):
print("Adding sugar and milk")

# Клиентский код для использования паттерна Шаблонный метод
def main():
tea = Tea()
coffee = Coffee()

print("Making tea:")
tea.prepare_recipe()

print("\nMaking coffee:")
coffee.prepare_recipe()

if __name__ == "__main__":
main()


🚩Как это работает

1⃣Абстрактный класс `CaffeineBeverage`
Определяет шаблонный метод prepare_recipe, который описывает последовательность шагов алгоритма.
2⃣Методы `boil_water` и `pour_in_cup`
Реализованы в абстрактном классе, так как они одинаковы для всех напитков.
3⃣Абстрактные методы `brew` и `add_condiments`
Объявлены в абстрактном классе и должны быть реализованы в подклассах.
4⃣Подклассы `Tea` и `Coffee`
Реализуют методы brew и add_condiments, определяя конкретные шаги для приготовления чая и кофе.

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