🤔 Что такое клиент-серверная архитектура?
Клиент-серверная архитектура – это модель взаимодействия устройств, где клиент запрашивает данные или услуги, а сервер их предоставляет.
🚩Как это работает?
Клиент – это программа или устройство, которое отправляет запросы (например, браузер).
Сервер – это программа или устройство, которое обрабатывает запросы и отправляет ответ (например, веб-сервер).
Сервер (сервер.py)
Клиент (клиент.py)
🚩Как это работает?
1⃣Запускаем
2⃣Запускаем
3⃣Сервер получает сообщение, отвечает клиенту и закрывает соединение.
4⃣Клиент принимает ответ и завершает работу.
🚩Типы клиент-серверных архитектур
Одноуровневая – клиент общается напрямую с сервером.
Двухуровневая – классическая схема "клиент сервер" (например, браузер веб-сервер).
Трёхуровневая – добавляется база данных (например, клиент сервер БД).
Многоуровневая – сложные распределённые системы с несколькими серверами (например, микросервисы).
Ставь 👍 и забирай 📚 Базу знаний
Клиент-серверная архитектура – это модель взаимодействия устройств, где клиент запрашивает данные или услуги, а сервер их предоставляет.
🚩Как это работает?
Клиент – это программа или устройство, которое отправляет запросы (например, браузер).
Сервер – это программа или устройство, которое обрабатывает запросы и отправляет ответ (например, веб-сервер).
Сервер (сервер.py)
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 8080)) # Привязываем сервер к адресу и порту
server.listen(1) # Ожидаем подключения одного клиента
print("Сервер запущен и ждёт подключения...")
conn, addr = server.accept() # Принимаем подключение
print(f"Подключен клиент: {addr}")
data = conn.recv(1024).decode() # Читаем данные от клиента
print(f"Клиент прислал: {data}")
conn.send("Привет от сервера!".encode()) # Отправляем ответ клиенту
conn.close()
Клиент (клиент.py)
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 8080)) # Подключаемся к серверу
client.send("Привет, сервер!".encode()) # Отправляем сообщение
response = client.recv(1024).decode() # Получаем ответ от сервера
print(f"Ответ сервера: {response}")
client.close()
🚩Как это работает?
1⃣Запускаем
сервер.py. Он ждёт подключения. 2⃣Запускаем
клиент.py. Клиент подключается к серверу и отправляет сообщение. 3⃣Сервер получает сообщение, отвечает клиенту и закрывает соединение.
4⃣Клиент принимает ответ и завершает работу.
🚩Типы клиент-серверных архитектур
Одноуровневая – клиент общается напрямую с сервером.
Двухуровневая – классическая схема "клиент сервер" (например, браузер веб-сервер).
Трёхуровневая – добавляется база данных (например, клиент сервер БД).
Многоуровневая – сложные распределённые системы с несколькими серверами (например, микросервисы).
Ставь 👍 и забирай 📚 Базу знаний
👍9
🤔 Что делать, если нужно сериализовать данные, которые не поддерживаются стандартным модулем json?
Можно передать параметр default с функцией, преобразующей неподдерживаемые объекты. Либо использовать другой модуль, например pickle.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Можно передать параметр default с функцией, преобразующей неподдерживаемые объекты. Либо использовать другой модуль, например pickle.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🤔3
🤔 Какие объекты можно положить в множество?
В Python множество (
🚩Можно добавить в `set`:
Числа (
Строки (
Кортежи (
Булевые значения (
🚩Нельзя добавить в `set`
Изменяемые объекты (
Кортежи с изменяемыми элементами
Ставь 👍 и забирай 📚 Базу знаний
В Python множество (
set) — это неупорядоченная коллекция уникальных элементов, которая работает на основе хеш-таблицы. Это значит, что только хешируемые (immutable) объекты могут быть добавлены в set.🚩Можно добавить в `set`:
Числа (
int, float, complex) s = {1, 2.5, 3+4j}Строки (
str) s = {"apple", "banana", "cherry"}Кортежи (
tuple), если они тоже содержат только неизменяемые объекты s = {(1, 2), ("a", "b")}Булевые значения (
bool)** (но True считается 1, а False — 0) s = {True, False, 1, 0}
print(s) # {False, True} (0 и 1 не добавятся повторно)🚩Нельзя добавить в `set`
Изменяемые объекты (
list, set, dict) s = { [1, 2, 3] } # Ошибка: TypeError: unhashable type: 'list' s = { {"key": "value"} } # Ошибка: TypeError: unhashable type: 'dict'Кортежи с изменяемыми элементами
s = { (1, [2, 3]) } # Ошибка: TypeErrorСтавь 👍 и забирай 📚 Базу знаний
👍8
🤔 Что такое абстракция?
Это принцип объектно-ориентированного программирования, позволяющий скрывать детали реализации и предоставлять пользователю только необходимый интерфейс. Это помогает уменьшить сложность системы, улучшить читаемость кода и упростить поддержку за счет сокрытия ненужных деталей.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍6🔥2💊1
🤔 Какие есть особенности исключения в Python?
В Python исключения (
Все исключения в Python — это объекты, унаследованные от
Все исключения унаследованы от
Можно перехватывать несколько исключений
Если не знаем, какая ошибка может произойти:
Можно создать свой класс ошибки, унаследованный от
Ставь 👍 и забирай 📚 Базу знаний
В Python исключения (
exceptions) — это специальные объекты, которые возникают при ошибках и прерывают выполнение программы, если их не обработать.Все исключения в Python — это объекты, унаследованные от
BaseException. try:
1 / 0
except ZeroDivisionError as e:
print(type(e)) # <class 'ZeroDivisionError'>
print(e) # division by zero
Все исключения унаследованы от
BaseException: BaseException
├── Exception
│ ├── ArithmeticError
│ │ ├── ZeroDivisionError
│ │ ├── OverflowError
│ ├── ValueError
│ ├── IndexError
│ ├── KeyError
│ ├── TypeError
├── SystemExit
├── KeyboardInterrupt
Можно перехватывать несколько исключений
try:
x = int("abc") # Ошибка ValueError
except (ValueError, TypeError) as e:
print(f"Ошибка: {e}")
Если не знаем, какая ошибка может произойти:
try:
x = 1 / 0
except Exception as e:
print(f"Ошибка: {e}") # division by zero
finally выполняется всегда try:
1 / 0
except ZeroDivisionError:
print("Ошибка!")
finally:
print("Этот код выполнится всегда")
raise позволяет выбрасывать исключения вручную raise ValueError("Ошибка: неверное значение!")Можно создать свой класс ошибки, унаследованный от
Exception: class MyError(Exception):
pass
raise MyError("Это моя ошибка!")
Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Как работают вложенные исключения?
Вложенные исключения в Python — это конструкция, при которой один блок try находится внутри другого. Это позволяет локально обрабатывать определённые ошибки, не прерывая выполнения внешнего блока.
Если исключение перехвачено во внутреннем try-except, то внешний except не срабатывает. Если не перехвачено — передаётся дальше по стеку вверх.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Вложенные исключения в Python — это конструкция, при которой один блок try находится внутри другого. Это позволяет локально обрабатывать определённые ошибки, не прерывая выполнения внешнего блока.
Если исключение перехвачено во внутреннем try-except, то внешний except не срабатывает. Если не перехвачено — передаётся дальше по стеку вверх.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5
🤔 Какие есть виды файловых объектов?
В Python существует несколько типов файловых объектов, которые используются для работы с различными типами данных. Рассмотрим основные виды файловых объектов и их особенности.
🟠Текстовые файлы (`TextIOWrapper`)
Это самый распространённый тип файловых объектов. Такие файлы используются для работы с текстовыми данными и поддерживают строковые операции.
🟠Бинарные файлы (`BufferedReader`, `BufferedWriter`)
Эти файлы используются для работы с двоичными данными (изображениями, видео, аудиофайлами и т. д.).
🟠Файлы ввода-вывода в памяти (`io.StringIO`, `io.BytesIO`)
Эти объекты представляют собой файловые буферы, которые хранят данные в оперативной памяти, а не на диске.
Пример работы с
🟠Файловые объекты на основе сокетов, пайпов и других источников
Python позволяет работать с файловыми объектами, полученными из нестандартных источников, например, сокетов или каналов связи (
Ставь 👍 и забирай 📚 Базу знаний
В Python существует несколько типов файловых объектов, которые используются для работы с различными типами данных. Рассмотрим основные виды файловых объектов и их особенности.
🟠Текстовые файлы (`TextIOWrapper`)
Это самый распространённый тип файловых объектов. Такие файлы используются для работы с текстовыми данными и поддерживают строковые операции.
with open("example.txt", "w", encoding="utf-8") as file:
file.write("Привет, мир!") # Записываем текст в файл
with open("example.txt", "r", encoding="utf-8") as file:
content = file.read() # Читаем текст из файла
print(content)🟠Бинарные файлы (`BufferedReader`, `BufferedWriter`)
Эти файлы используются для работы с двоичными данными (изображениями, видео, аудиофайлами и т. д.).
with open("image.jpg", "rb") as file:
binary_data = file.read() # Читаем файл в бинарном режиме
print(binary_data[:10]) # Выведем первые 10 байтов
with open("copy.jpg", "wb") as file:
file.write(binary_data) # Записываем данные в новый файл🟠Файлы ввода-вывода в памяти (`io.StringIO`, `io.BytesIO`)
Эти объекты представляют собой файловые буферы, которые хранят данные в оперативной памяти, а не на диске.
from io import StringIO
file = StringIO()
file.write("Привет, мир!") # Запись данных в буфер
file.seek(0) # Перемещаем указатель в начало
print(file.read()) # Читаем данные из буфера
Пример работы с
BytesIO:from io import BytesIO
file = BytesIO()
file.write(b"Binary data") # Запись бинарных данных
file.seek(0)
print(file.read()) # Чтение данных
🟠Файловые объекты на основе сокетов, пайпов и других источников
Python позволяет работать с файловыми объектами, полученными из нестандартных источников, например, сокетов или каналов связи (
pipes).import socket
s = socket.socket()
s.connect(("example.com", 80))
s.sendall(b"GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
response = s.makefile("r", encoding="utf-8") # Создание файлового объекта
print(response.readline()) # Читаем первую строку HTTP-ответа
s.close()
Ставь 👍 и забирай 📚 Базу знаний
👍7
🤔 Почему индекс списка начинается с нуля?
Индексация с нуля исторически пришла из языков вроде C, где array[0] означает смещение от начала памяти. Это упрощает адресацию и математические операции при обходе массивов, и Python унаследовал этот подход как более логичный и эффективный.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Индексация с нуля исторически пришла из языков вроде C, где array[0] означает смещение от начала памяти. Это упрощает адресацию и математические операции при обходе массивов, и Python унаследовал этот подход как более логичный и эффективный.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍11
🤔 Что такое хранитель (Memento)?
Это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать предыдущее состояние объекта без нарушения инкапсуляции. Этот паттерн особенно полезен для реализации операций отмены и повтора, так как он позволяет хранить состояния объектов и возвращать их к этим состояниям по необходимости.
🚩Зачем нужен?
🟠Сохранение состояния:
Позволяет сохранять текущее состояние объекта и восстанавливать его позже.
🟠Инкапсуляция:
Обеспечивает сохранение состояния объекта без нарушения его инкапсуляции. Внутренние детали объекта остаются скрытыми от других объектов.
🟠Отмена и повтор операций:
Поддерживает функциональность отмены и повтора операций, так как позволяет возвращать объект к предыдущим состояниям.
Пример реализации
1⃣`Memento`:
Сохраняет состояние объекта. Он предоставляет методы для получения сохраненного состояния, но не предоставляет методов для изменения состояния, что обеспечивает неизменность.
2⃣`TextEditor`:
Создает и использует объекты
3⃣`_save_state`:
Сохраняет текущее состояние редактора в истории перед каждым изменением.
4⃣`undo`:
Восстанавливает предыдущее состояние редактора из истории.
Ставь 👍 и забирай 📚 Базу знаний
Это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать предыдущее состояние объекта без нарушения инкапсуляции. Этот паттерн особенно полезен для реализации операций отмены и повтора, так как он позволяет хранить состояния объектов и возвращать их к этим состояниям по необходимости.
🚩Зачем нужен?
🟠Сохранение состояния:
Позволяет сохранять текущее состояние объекта и восстанавливать его позже.
🟠Инкапсуляция:
Обеспечивает сохранение состояния объекта без нарушения его инкапсуляции. Внутренние детали объекта остаются скрытыми от других объектов.
🟠Отмена и повтор операций:
Поддерживает функциональность отмены и повтора операций, так как позволяет возвращать объект к предыдущим состояниям.
Пример реализации
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`:
Восстанавливает предыдущее состояние редактора из истории.
Ставь 👍 и забирай 📚 Базу знаний
👍3
🤔 Что такое set?
Множество в Python — это неупорядоченная коллекция уникальных элементов. Оно используется для удаления дубликатов, а также для выполнения операций теории множеств — пересечения, объединения, разности. Это быстрый и удобный тип данных для работы с наборами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Множество в Python — это неупорядоченная коллекция уникальных элементов. Оно используется для удаления дубликатов, а также для выполнения операций теории множеств — пересечения, объединения, разности. Это быстрый и удобный тип данных для работы с наборами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍8
🤔 Почему поиск по ключам в словаре работает быстро?
В Python словари (
🟠Как устроен словарь в Python?
Словарь (
🟠Как работает хеш-таблица?
Основной принцип:
Хеш-функция (
Используется массив (таблица), где данные хранятся по индексам, связанным с хешем.
Поиск по ключу — это просто вычисление хеша и обращение к нужному индексу.
Когда мы пишем
🟠Почему поиск занимает O(1)?
Нет линейного поиска: вместо перебора всех элементов Python сразу вычисляет, где находится нужное значение.
Операция доступа занимает фиксированное время:
Даже при большом количестве элементов скорость остается высокой.
Добавим 1 миллион элементов и посмотрим скорость поиска:
🟠Что если хеши совпадут? (Коллизии)
Иногда два разных ключа могут иметь одинаковый хеш (редко, но возможно). Тогда Python использует связанный список (chaining) или перехеширование.
Ставь 👍 и забирай 📚 Базу знаний
В Python словари (
dict) работают очень быстро, потому что они используют хеш-таблицы. Это позволяет находить значения по ключу в константное время O(1) в большинстве случаев. Давайте разберемся, как это работает.🟠Как устроен словарь в Python?
Словарь (
dict) — это структура данных, которая хранит пары ключ → значение. Например:data = {"name": "Alice", "age": 25, "city": "New York"}
print(data["age"]) # 25🟠Как работает хеш-таблица?
Основной принцип:
Хеш-функция (
hash()) вычисляет уникальное число (хеш) для ключа.Используется массив (таблица), где данные хранятся по индексам, связанным с хешем.
Поиск по ключу — это просто вычисление хеша и обращение к нужному индексу.
print(hash("age")) # Например, вернет 328847234 (будет разным при каждом запуске)Когда мы пишем
value = data["age"]
🟠Почему поиск занимает O(1)?
Нет линейного поиска: вместо перебора всех элементов Python сразу вычисляет, где находится нужное значение.
Операция доступа занимает фиксированное время:
hash() + обращение по индексу.Даже при большом количестве элементов скорость остается высокой.
Добавим 1 миллион элементов и посмотрим скорость поиска:
import time
data = {i: i * 2 for i in range(1_000_000)}
start = time.time()
print(data[999_999]) # Быстро находит ключ!
end = time.time()
print("Время поиска:", end - start) # Около 0.000001 сек
🟠Что если хеши совпадут? (Коллизии)
Иногда два разных ключа могут иметь одинаковый хеш (редко, но возможно). Тогда Python использует связанный список (chaining) или перехеширование.
print(hash("abc") % 10) # Например, 5
print(hash("xyz") % 10) # Тоже 5 (редко, но бывает)Ставь 👍 и забирай 📚 Базу знаний
👍9🤔1
🤔 Что такое сокеты?
Это программный интерфейс (API), через который приложения обмениваются данными по сети.
Сокет — это конечная точка соединения, обеспечивающая передачу данных между двумя узлами (обычно по TCP или UDP).
Используется для:
- Клиент-серверных приложений.
- Чатов, игр, систем в реальном времени.
- Веб-сокетов (WebSocket) для двусторонней связи по HTTP(S).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Это программный интерфейс (API), через который приложения обмениваются данными по сети.
Сокет — это конечная точка соединения, обеспечивающая передачу данных между двумя узлами (обычно по TCP или UDP).
Используется для:
- Клиент-серверных приложений.
- Чатов, игр, систем в реальном времени.
- Веб-сокетов (WebSocket) для двусторонней связи по HTTP(S).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥8👍4
🤔 Что такое IP адрес и доменное имя?
Это два важных понятия в контексте работы интернета и компьютерных сетей. Они используются для идентификации устройств и ресурсов в сети, а также для упрощения доступа к ним.
🚩IP-адрес (Internet Protocol Address)
Это уникальный числовой идентификатор, присваиваемый каждому устройству, подключенному к сети, использующей протокол IP (Internet Protocol). IP-адреса используются для маршрутизации пакетов данных между устройствами в сети.
🟠IPv4 (Internet Protocol version 4)
Формат: 32-битные числа, записанные в виде четырех десятичных чисел, разделенных точками (например, 192.168.1.1). Пример: 192.168.0.1, 8.8.8.8
🟠IPv6 (Internet Protocol version 6)
Формат: 128-битные числа, записанные в виде восьми групп шестнадцатеричных чисел, разделенных двоеточиями (например, 2001:0db8:85a3:0000:0000:8a2e:0370:7334). Пример: 2001:0db8:85a3:0000:0000:8a2e:0370:7334, ::1 (loopback адрес)
🚩Доменное имя
Это удобочитаемое имя, используемое для идентификации IP-адреса на уровне пользователя. Доменные имена упрощают доступ к ресурсам в интернете, так как их легче запомнить и использовать, чем числовые IP-адреса.
🟠Top-Level Domain (TLD)
Верхний уровень, например, .com, .org, .net.
🟠Second-Level Domain (SLD)
Основная часть доменного имени, например, example в example.com.
🟠Subdomain
Дополнительные уровни, например, www в www.example.com.
🚩Преобразование доменных имен в IP-адреса
Для преобразования доменных имен в IP-адреса используется система доменных имен (DNS, Domain Name System). DNS-серверы выполняют роль "телефонной книги" интернета, переводя доменные имена в соответствующие им IP-адреса.
Ставь 👍 и забирай 📚 Базу знаний
Это два важных понятия в контексте работы интернета и компьютерных сетей. Они используются для идентификации устройств и ресурсов в сети, а также для упрощения доступа к ним.
🚩IP-адрес (Internet Protocol Address)
Это уникальный числовой идентификатор, присваиваемый каждому устройству, подключенному к сети, использующей протокол IP (Internet Protocol). IP-адреса используются для маршрутизации пакетов данных между устройствами в сети.
🟠IPv4 (Internet Protocol version 4)
Формат: 32-битные числа, записанные в виде четырех десятичных чисел, разделенных точками (например, 192.168.1.1). Пример: 192.168.0.1, 8.8.8.8
🟠IPv6 (Internet Protocol version 6)
Формат: 128-битные числа, записанные в виде восьми групп шестнадцатеричных чисел, разделенных двоеточиями (например, 2001:0db8:85a3:0000:0000:8a2e:0370:7334). Пример: 2001:0db8:85a3:0000:0000:8a2e:0370:7334, ::1 (loopback адрес)
🚩Доменное имя
Это удобочитаемое имя, используемое для идентификации IP-адреса на уровне пользователя. Доменные имена упрощают доступ к ресурсам в интернете, так как их легче запомнить и использовать, чем числовые IP-адреса.
🟠Top-Level Domain (TLD)
Верхний уровень, например, .com, .org, .net.
🟠Second-Level Domain (SLD)
Основная часть доменного имени, например, example в example.com.
🟠Subdomain
Дополнительные уровни, например, www в www.example.com.
🚩Преобразование доменных имен в IP-адреса
Для преобразования доменных имен в IP-адреса используется система доменных имен (DNS, Domain Name System). DNS-серверы выполняют роль "телефонной книги" интернета, переводя доменные имена в соответствующие им IP-адреса.
Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Может ли сервер изменить (добавить, удалить) куки?
Да, сервер управляет куками через заголовок Set-Cookie. Он может отправить новые, обновить существующие или установить срок действия, после которого cookie удалится автоматически. Также можно указать флаг удаления, отправив cookie с истёкшим сроком.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥3👍2
🤔 Зачем нужен volume в docker?
В Docker
🚩Зачем нужен `volume`?
Данные не теряются при удалении контейнера
Общий доступ: несколько контейнеров могут использовать один и тот же
Производительность: тома быстрее, чем хранение внутри контейнера
Разделение кода и данных: удобно для баз данных и логов
🚩Как создать `volume`?
Способ 1: Автоматическое создание при запуске контейнера
Способ 2: Создать том отдельно и подключить его
Способ 3: Использовать путь на хосте (bind-mount)
🚩Как посмотреть список томов?
🚩Как удалить `volume`?
Важно: при удалении тома данные удаляются безвозвратно!
Ставь 👍 и забирай 📚 Базу знаний
В Docker
volume (том) — это специальное место для хранения данных контейнера, которое не исчезает при перезапуске или удалении контейнера. 🚩Зачем нужен `volume`?
Данные не теряются при удалении контейнера
Общий доступ: несколько контейнеров могут использовать один и тот же
volume Производительность: тома быстрее, чем хранение внутри контейнера
Разделение кода и данных: удобно для баз данных и логов
🚩Как создать `volume`?
Способ 1: Автоматическое создание при запуске контейнера
docker run -d -v my_volume:/app/data my_container
Способ 2: Создать том отдельно и подключить его
docker volume create my_volume
docker run -d -v my_volume:/app/data my_container
Способ 3: Использовать путь на хосте (bind-mount)
docker run -d -v /home/user/data:/app/data my_container
🚩Как посмотреть список томов?
docker volume ls # Покажет все тома
docker volume inspect my_volume # Информация о томе
🚩Как удалить `volume`?
Важно: при удалении тома данные удаляются безвозвратно!
docker volume rm my_volume # Удаление одного тома
docker volume prune # Удаление всех неиспользуемых томов
Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Как описать модель проектирования?
Использует шаблон MVC (Model-View-Controller), но адаптирован под MTV (Model-Template-View). Основные компоненты:
- Model — представляет данные и логику базы данных
- Template — отвечает за отображение
- View — обрабатывает логику запроса и ответа
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Использует шаблон MVC (Model-View-Controller), но адаптирован под MTV (Model-Template-View). Основные компоненты:
- Model — представляет данные и логику базы данных
- Template — отвечает за отображение
- View — обрабатывает логику запроса и ответа
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊6👍4🤔2
🤔 Как отсортировать список словарей по определенному полю?
Для сортировки списка словарей по определенному полю в Python удобно использовать функцию sorted() или метод sort(). Оба подхода позволяют указать ключ сортировки с помощью параметра key, где можно передать либо функцию, либо лямбда-выражение, которое извлекает значение из словаря для сортировки.
🚩Почему это важно?
Списки словарей часто используются для хранения структурированных данных. Например, вы можете иметь список сотрудников, где каждый сотрудник представлен в виде словаря с полями, такими как имя, возраст и зарплата. Сортировка по определенному полю позволяет упорядочить данные, чтобы ими было проще пользоваться или отображать.
🚩Как это сделать?
🟠Использование функции `sorted()`
Эта функция возвращает новый отсортированный список.
Результат
🟠Использование метода `sort()`
Этот метод изменяет существующий список.
Результат
🟠Сортировка в обратном порядке
Установите параметр reverse=True, чтобы отсортировать в порядке убывания.
🟠Использование функции `itemgetter` из модуля `operator`
Это более эффективный способ, чем лямбда-функция, особенно для больших данных.
🚩Обработка отсутствующих значений
Если поле может отсутствовать в некоторых словарях, можно использовать параметр key для обработки таких ситуаций.
Результат
Ставь 👍 и забирай 📚 Базу знаний
Для сортировки списка словарей по определенному полю в Python удобно использовать функцию sorted() или метод sort(). Оба подхода позволяют указать ключ сортировки с помощью параметра key, где можно передать либо функцию, либо лямбда-выражение, которое извлекает значение из словаря для сортировки.
🚩Почему это важно?
Списки словарей часто используются для хранения структурированных данных. Например, вы можете иметь список сотрудников, где каждый сотрудник представлен в виде словаря с полями, такими как имя, возраст и зарплата. Сортировка по определенному полю позволяет упорядочить данные, чтобы ими было проще пользоваться или отображать.
🚩Как это сделать?
🟠Использование функции `sorted()`
Эта функция возвращает новый отсортированный список.
employees = [
{"name": "Alice", "age": 30, "salary": 70000},
{"name": "Bob", "age": 25, "salary": 50000},
{"name": "Charlie", "age": 35, "salary": 120000}
]
# Сортировка по возрасту
sorted_employees = sorted(employees, key=lambda x: x["age"])
print(sorted_employees)
Результат
[{'name': 'Bob', 'age': 25, 'salary': 50000},
{'name': 'Alice', 'age': 30, 'salary': 70000},
{'name': 'Charlie', 'age': 35, 'salary': 120000}]
🟠Использование метода `sort()`
Этот метод изменяет существующий список.
employees = [
{"name": "Alice", "age": 30, "salary": 70000},
{"name": "Bob", "age": 25, "salary": 50000},
{"name": "Charlie", "age": 35, "salary": 120000}
]
# Сортировка по зарплате
employees.sort(key=lambda x: x["salary"])
print(employees)
Результат
[{'name': 'Bob', 'age': 25, 'salary': 50000},
{'name': 'Alice', 'age': 30, 'salary': 70000},
{'name': 'Charlie', 'age': 35, 'salary': 120000}]
🟠Сортировка в обратном порядке
Установите параметр reverse=True, чтобы отсортировать в порядке убывания.
sorted_employees_desc = sorted(employees, key=lambda x: x["age"], reverse=True)
print(sorted_employees_desc)
🟠Использование функции `itemgetter` из модуля `operator`
Это более эффективный способ, чем лямбда-функция, особенно для больших данных.
from operator import itemgetter
sorted_employees = sorted(employees, key=itemgetter("age"))
print(sorted_employees)
🚩Обработка отсутствующих значений
Если поле может отсутствовать в некоторых словарях, можно использовать параметр key для обработки таких ситуаций.
employees = [
{"name": "Alice", "age": 30},
{"name": "Bob"},
{"name": "Charlie", "age": 35}
]
sorted_employees = sorted(employees, key=lambda x: x.get("age", 0))
print(sorted_employees)
Результат
[{'name': 'Bob'},
{'name': 'Alice', 'age': 30},
{'name': 'Charlie', 'age': 35}]Ставь 👍 и забирай 📚 Базу знаний
👍4
🤔 Какие есть особенности исключений?
1. Все исключения являются объектами и наследуются от базового класса BaseException (обычно от Exception).
2. Обработка исключений осуществляется через блоки try-except, с возможностью использовать else (если исключения не было) и finally (выполняется всегда).
3. Можно обрабатывать конкретные типы ошибок, в том числе несколько сразу:
4. Можно создавать собственные исключения, унаследовав их от Exception.
5. Исключения можно перекидывать вверх по стеку с помощью raise.
6. В Python принято использовать исключения для управления потоком, особенно при обработке ввода, сетевых операций, доступа к данным и API.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
2. Обработка исключений осуществляется через блоки try-except, с возможностью использовать else (если исключения не было) и finally (выполняется всегда).
3. Можно обрабатывать конкретные типы ошибок, в том числе несколько сразу:
4. Можно создавать собственные исключения, унаследовав их от Exception.
5. Исключения можно перекидывать вверх по стеку с помощью raise.
6. В Python принято использовать исключения для управления потоком, особенно при обработке ввода, сетевых операций, доступа к данным и API.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4
🤔 Почему вычислять большие значения в асинхронной функции плохо?
Асинхронность (
Если в
🚩Асинхронность в Python подходит для ввода-вывода (I/O-bound)
Асинхронность позволяет выполнять задачи без блокировки, но только если они ждут чего-то (файлы, сеть, БД).
🚩Проблема с `async` и тяжёлыми вычислениями (CPU-bound)
Если в
🚩Как правильно выполнять вычисления в `async`?
🟠Использовать `asyncio.to_thread()` (делегирование в потоки)
В Python 3.9+ можно выполнять CPU-задачи в отдельных потоках, не блокируя
🟠Использовать `multiprocessing` (запуск на нескольких ядрах)
Так как Python использует GIL, единственный способ выполнять настоящий параллелизм — это
Ставь 👍 и забирай 📚 Базу знаний
Асинхронность (
asyncio) в Python не выполняет код параллельно, а переключается между задачами во время ожидания (I/O-bound). Если в
async-функции делать тяжёлые вычисления (CPU-bound), это блокирует asyncio, потому что в Python есть GIL (Global Interpreter Lock). 🚩Асинхронность в Python подходит для ввода-вывода (I/O-bound)
Асинхронность позволяет выполнять задачи без блокировки, но только если они ждут чего-то (файлы, сеть, БД).
import asyncio
import aiohttp
async def fetch(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = ["https://example.com"] * 5
results = await asyncio.gather(*(fetch(url) for url in urls))
asyncio.run(main())
🚩Проблема с `async` и тяжёлыми вычислениями (CPU-bound)
Если в
async-функции делать тяжёлые вычисления, Python не сможет переключаться между задачами. import asyncio
async def heavy_task(n):
print(f"Вычисляю {n}...")
total = sum(i**2 for i in range(n)) # Долгий процесс
return total
async def main():
await asyncio.gather(heavy_task(10**7), heavy_task(10**7))
asyncio.run(main())
🚩Как правильно выполнять вычисления в `async`?
🟠Использовать `asyncio.to_thread()` (делегирование в потоки)
В Python 3.9+ можно выполнять CPU-задачи в отдельных потоках, не блокируя
asyncio. import asyncio
def heavy_computation(n):
return sum(i**2 for i in range(n))
async def main():
result = await asyncio.to_thread(heavy_computation, 10**7)
print(result)
asyncio.run(main())
🟠Использовать `multiprocessing` (запуск на нескольких ядрах)
Так как Python использует GIL, единственный способ выполнять настоящий параллелизм — это
multiprocessing.import asyncio
import multiprocessing
def heavy_computation(n):
return sum(i**2 for i in range(n))
async def main():
loop = asyncio.get_running_loop()
with multiprocessing.Pool() as pool:
result = await loop.run_in_executor(pool, heavy_computation, 10**7)
print(result)
asyncio.run(main())
Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 Что такое байт-код?
Это промежуточное представление программы, которое создаётся после компиляции Python-кода. Он исполняется виртуальной машиной Python (интерпретатором).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Это промежуточное представление программы, которое создаётся после компиляции Python-кода. Он исполняется виртуальной машиной Python (интерпретатором).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍3