Это подход к проектированию веб-сервисов, основанный на архитектурном стиле REST (*Representational State Transfer*). Это не протокол или стандарт, а набор принципов и ограничений, которые используются для создания систем, взаимодействующих через HTTP. Если API соответствует этим принципам, его называют RESTful.
Клиент (например, браузер или мобильное приложение) и сервер (где размещена база данных и логика обработки данных) чётко разделены:
Клиент запрашивает данные или отправляет запросы к серверу.
Сервер отвечает, предоставляя ресурсы или выполняя действия.
Каждый запрос от клиента к серверу должен быть самодостаточным. Это означает, что сервер не хранит информацию о состоянии клиента между запросами. Вся необходимая информация передается в запросе (например, токен аутентификации).
RESTful API использует единый, стандартный интерфейс для взаимодействия. Это достигается следующими средствами:
Идентификация ресурсов через URI: Каждый ресурс имеет уникальный адрес (URI).
GET https://api.example.com/users/123
Использование стандартных HTTP-методов:
GET — для получения данных.
POST — для создания новых данных.
PUT или PATCH — для обновления данных.
DELETE — для удаления данных.
Ресурсы как представления: Ресурсы передаются в формате JSON, XML или другом формате.
Ответы сервера могут быть кэшируемыми. Это уменьшает нагрузку на сервер и ускоряет работу клиента.
RESTful системы могут включать несколько слоев (например, балансировщики нагрузки, кеш-сервисы), но клиент взаимодействует только с сервером, не зная о внутренних слоях.
Иногда сервер может передавать исполняемый код (например, JavaScript) клиенту, чтобы расширить его функциональность. Это не обязательно.
RESTful архитектура позволяет:
Клиенты легко понимают, как обращаться к ресурсам (используя стандартные методы и адреса).
Клиенты и серверы могут развиваться независимо друг от друга.
RESTful API легко масштабируются, так как все запросы независимы друг от друга (статичность).
RESTful API поддерживают стандартизированные протоколы (HTTP), что делает интеграцию с другими сервисами проще.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Пакет в Python — это папка с файлом __init__.py, содержащая модули или подпакеты. Он позволяет структурировать код и использовать иерархический импорт:
from mypackage.submodule import my_function
Пакет — это способ логически разделить код на части, удобные для поддержки, переиспользования и тестирования.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💊2
Сортировка слиянием (
Merge Sort) — это алгоритм, который использует разделяй и властвуй (divide & conquer). В худшем случае сложность O(n log n).
до тех пор, пока не останутся отдельные элементы.
полученные подмассивы.
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
sorted_arr = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
sorted_arr.append(left[i])
i += 1
else:
sorted_arr.append(right[j])
j += 1
sorted_arr.extend(left[i:])
sorted_arr.extend(right[j:])
return sorted_arr
arr = [5, 2, 9, 1, 5, 6]
print(merge_sort(arr))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Это метод решения задач, при котором большая задача разбивается на перекрывающиеся подзадачи, результаты которых запоминаются (мемоизируются). Подходит для оптимизационных задач: рюкзак, наибольшая общая подпоследовательность, пути в решётке.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🤔1
Кэширование в HTTP позволяет уменьшить нагрузку на сервер и ускорить загрузку страниц за счёт сохранения копий ресурсов.
Управление кэшем происходит через HTTP-заголовки, которые указывают, как долго хранить данные и когда обновлять их.
Cache-Control — основной заголовок для кэширования, который указывает, как долго хранить ресурс и когда обновлять его.Cache-Control: no-cache # Браузер всегда запрашивает ресурс заново
Cache-Control: no-store # Запрещает кэширование вообще
Cache-Control: public, max-age=3600 # Кэшировать 1 час (3600 секунд)
Cache-Control: private, max-age=600 # Кэш только для одного пользователя (например, личный кабинет)
Cache-Control: must-revalidate # Клиент должен проверять, истёк ли срок кэша перед загрузкой
ETag — это уникальный идентификатор версии файла. Сервер отправляет ресурс с
ETag: ETag: "abc123"
При следующем запросе браузер отправляет
If-None-Match: If-None-Match: "abc123"
Если ресурс не изменился, сервер отвечает
304 Not Modified (клиент использует кэш). Если ресурс изменился — сервер отправляет новую версию.
HTTP/1.1 304 Not Modified
Работает аналогично
ETag, но вместо идентификатора используется дата последнего изменения.Сервер отправляет заголовок
Last-Modified: Wed, 21 Feb 2024 10:00:00 GMT
Браузер запрашивает ресурс с
If-Modified-Since If-Modified-Since: Wed, 21 Feb 2024 10:00:00 GMT
Если нужно всегда загружать свежие данные, используем:
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache # Устарел, но нужен для старых браузеров
Expires: 0
Если ресурс зависит от заголовков (
User-Agent, Accept-Encoding), используем Vary.Vary: User-Agent
Если сервер отправил старый кэш, можно обновить ресурс с новым URL.
Способы
Добавить версию в URL
/style.css?v=2
Использовать хеш в имени файла:
/style.abc123.css
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
- Проверяет, является ли класс наследником другого.
- Синтаксис: issubclass(ChildClass, ParentClass).
Для проверки объекта: используйте isinstance():
- Определяет, принадлежит ли объект указанному классу или его потомку.
- Синтаксис: isinstance(obj, ParentClass).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2🤔1
Существует несколько видов тестов, каждый из которых имеет свою цель и особенности.
Проверка работы отдельных модулей или функций в изоляции от других частей системы.
Ориентированы на минимальные части кода (функции, методы, классы).
Высокая скорость выполнения.
Простота написания и отладки.
Обычно пишутся разработчиками.
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
Проверка взаимодействия между различными модулями или компонентами системы.
Тестируют комбинации модулей и их взаимодействие.
Более сложные и медленные по сравнению с юнит-тестами.
Могут выявить проблемы в интерфейсах между модулями.
def fetch_data_from_api():
response = requests.get('https://api.example.com/data')
return response.json()
def test_fetch_data_from_api():
data = fetch_data_from_api()
assert 'key' in data
Проверка всей системы целиком на соответствие требованиям.
Тестируют систему в рабочей среде.
Включают проверку всех функциональных и нефункциональных требований.
Могут включать пользовательские сценарии.
Тестирование веб-приложения на основе реальных пользовательских сценариев, включая проверку интерфейса, баз данных и API.
Проверка соответствия системы требованиям и ожиданиям заказчика или конечного пользователя.
Часто выполняются вместе с заказчиком или пользователем.
Фокусируются на бизнес-требованиях и пользовательских сценариях.
Успешное прохождение приемочных тестов является критерием готовности системы к выпуску.
Тестирование нового функционала с участием конечных пользователей для проверки его удобства и соответствия их ожиданиям.
Убедиться, что изменения в коде не вызвали новых ошибок в уже работающем функционале.
Выполняются после внесения изменений в код.
Обычно автоматизируются и включают повторное выполнение всех или части существующих тестов.
Повторное выполнение всех юнит-тестов и интеграционных тестов после рефакторинга кода.
Проверка нефункциональных аспектов системы, таких как производительность, безопасность, удобство использования и др.
Измеряют скорость выполнения, пропускную способность и время отклика системы.
Оценивают защищенность системы от угроз и атак.
Проверяют удобство и интуитивность пользовательского интерфейса.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Forwarded from Идущий к IT
🔥 Записал видос "Как за 3 минуты настроить Автоотклики на вакансии HeadHunter" больше не придется заниматься этой унылой рутиной
📺 Видео: https://youtu.be/G_FOwEGPwlw
Please open Telegram to view this post
VIEW IN TELEGRAM
Главное ограничение — это глубина рекурсии. Python по умолчанию ограничивает количество вложенных вызовов функций (обычно до 1000), чтобы избежать переполнения стека вызовов. Это значит, что слишком глубокая рекурсия приведёт к ошибке RecursionError.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Сортировка слиянием (
Merge Sort) — это алгоритм, который использует разделяй и властвуй (divide & conquer). В худшем случае сложность O(n log n).
до тех пор, пока не останутся отдельные элементы.
полученные подмассивы.
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
sorted_arr = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
sorted_arr.append(left[i])
i += 1
else:
sorted_arr.append(right[j])
j += 1
sorted_arr.extend(left[i:])
sorted_arr.extend(right[j:])
return sorted_arr
arr = [5, 2, 9, 1, 5, 6]
print(merge_sort(arr))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Плюсы:
- Гибкость схемы (нет фиксированной структуры).
- Масштабируемость (горизонтальная).
- Подходят для хранения JSON, графов, документов.
Минусы:
- Отсутствие стандартного языка запросов.
- Сложность транзакций и консистентности.
- Подходят не для всех типов задач.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Модуль
datetime позволяет работать с датами и временем, но по умолчанию он не поддерживает часовые пояса.from datetime import datetime
dt = datetime.now() # Получаем текущую дату и время
print(dt) # Например: 2024-02-28 14:30:00.123456
print(dt.tzinfo) # None (нет информации о часовом поясе)
Библиотека
pytz добавляет поддержку часовых поясов и позволяет работать с разными временными зонами. from datetime import datetime
import pytz
tz = pytz.timezone("Europe/Moscow") # Часовой пояс Москвы
dt = datetime.now(tz) # Получаем текущее время с учетом часового пояса
print(dt) # Например: 2024-02-28 17:30:00+03:00
print(dt.tzinfo) # Europe/Moscow
Создание
datetime с часовым поясом pytz dt = datetime(2024, 2, 28, 15, 0) # Наивная дата
tz = pytz.timezone("Europe/Moscow")
dt = tz.localize(dt) # Присваиваем часовой пояс
print(dt) # 2024-02-28 15:00:00+03:00
Конвертация времени между часовыми поясами
ny_tz = pytz.timezone("America/New_York")
ny_time = dt.astimezone(ny_tz)
print(ny_time) # Конвертированное время в Нью-ЙоркеИспользование UTC (лучший подход для серверов)
utc_now = datetime.now(pytz.UTC) # Текущее время в UTC
print(utc_now) # Например: 2024-02-28 14:30:00+00:00
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Циклический импорт возникает, когда два модуля импортируют друг друга напрямую. Это приводит к ситуации, при которой один из них ещё не завершил инициализацию, и попытка доступа к его атрибутам вызывает ошибку. Такие проблемы решаются переструктурированием кода или отложенным импортом.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
Django использует
sqlparse и asgiref как вспомогательные библиотеки для работы с SQL и асинхронностью. Разберём их назначение подробно. sqlparse (SQL Parser) — это библиотека для анализа, форматирования и обработки SQL-запросов. В Django она используется в админке, логах и отладке ORM. Форматирование SQL-запросов в
django.db.connection.queriesfrom django.db import connection
from sqlparse import format
queries = connection.queries # Получаем список SQL-запросов
for q in queries:
print(format(q["sql"], reindent=True, keyword_case="upper")) # Красивый SQL
Логирование SQL-запросов
sqlparse помогает Django красиво выводить SQL-запросы в DEBUG=True.Команда
sqlmigratepython manage.py sqlmigrate app_name 0001
asgiref (Asynchronous Server Gateway Interface Reference) — это библиотека, которая помогает Django работать в асинхронном (async) режиме. Django поддерживает ASGI с версии 3.0, и asgiref — это её обязательная зависимость.Django с версии 3.0 поддерживает асинхронные вьюхи, WebSockets и асинхронные базы данных (например, с
asyncpg).В
settings.py есть параметр:ASGI_APPLICATION = "myproject.asgi.application"
Django 4.x поддерживает асинхронные middleware через
asgiref.sync и asgiref.local.Django использует
sync_to_async() и async_to_sync() из asgiref:from asgiref.sync import sync_to_async
def sync_function():
return "Hello from sync!"
async_function = sync_to_async(sync_function)
print(async_function()) # Вызывает синхронную функцию в асинхронном коде
Позволяет хранить данные отдельно для каждого потока или запроса.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3👍1
Такие библиотеки, например boto3, позволяют:
- Управлять облачными сервисами AWS (EC2, S3, RDS и др.).
- Автоматизировать создание серверов, баз данных, хранилищ.
- Настраивать безопасность, балансировку, мониторинг.
То есть, это способ писать инфраструктурный код вместо ручной работы через веб-интерфейс AWS.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
В Python поиск переменной происходит по правилу LEGB, которое определяет порядок поиска в четырёх областях видимости:
Пример работы LEGB
x = "глобальная" # Global
def outer():
x = "охватывающая" # Enclosing
def inner():
x = "локальная" # Local
print(x) # Поиск начинается отсюда (L)
inner()
outer()
Вывод
локальная
Если нужно изменить глобальную переменную внутри функции, используем
globalx = 10 # Глобальная переменная
def modify_global():
global x
x = 20 # Меняем глобальную переменную
modify_global()
print(x) # 20
Если в вложенной функции нужно изменить переменную из enclosing-области, используем
nonlocaldef outer():
x = 10 # Переменная из enclosing-области
def inner():
nonlocal x
x = 20 # Меняем `x` в `outer()`
inner()
print(x) # 20
outer()
Если переменная не найдена в LEGB, Python выдаст
NameErrordef func():
print(y) # Ошибка: y не объявлена!
func()
Ошибка
NameError: name 'y' is not defined
Python в последнюю очереде проверяет встроенные функции (
print(), len(), sum() и т. д.). print = "Ошибка!" # Переопределили встроенную функцию
print("Hello") # TypeError: 'str' object is not callable
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Да, начиная с Python 3.7 порядок вставки в словарь сохраняется по умолчанию. Это означает, что словарь стал упорядоченной структурой данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
В SQL можно объединять данные из двух таблиц без использования
JOIN, используя альтернативные методы. Подзапрос (
subquery) позволяет выбрать данные из одной таблицы, используя данные из другой. Допустим, у нас есть две таблицы:
employees (id, name, department_id) departments (id, name)SELECT name,
(SELECT name FROM departments WHERE id = employees.department_id) AS department_name
FROM employees;
Можно фильтровать данные из одной таблицы, проверяя наличие значений в другой.
SELECT name
FROM employees
WHERE department_id IN (SELECT id FROM departments);
Если таблицы имеют схожие колонки, можно объединить их с
UNION. SELECT id, name, email FROM users_old
UNION
SELECT id, name, email FROM users_new;
Хотя
CROSS JOIN делает декартово произведение, его можно фильтровать WHERE, имитируя INNER JOIN. SELECT e.name, d.name AS department
FROM employees e, departments d
WHERE e.department_id = d.id;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
- Create (создание),
- Read (чтение),
- Update (обновление),
- Delete (удаление).
Используется как в базах данных, так и в REST API.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Это специальный метод, который вызывается автоматически, когда объект класса уничтожается. В Python этот метод называется
__del__(). Деструктор используется для выполнения операций очистки, таких как освобождение ресурсов или выполнение завершающих действий перед тем, как объект будет удален из памяти.Определяется внутри класса с помощью метода
__del__(). class FileManager:
def __init__(self, filename):
self.file = open(filename, 'w')
print(f"Файл {filename} открыт для записи.")
def write_data(self, data):
self.file.write(data)
def __del__(self):
self.file.close()
print("Файл закрыт.")
FileManager имеет конструктор __init__(), который открывает файл для записи.write_data() записывает данные в файл.__del__() закрывает файл, когда объект FileManager уничтожается.Когда объект класса создается, вызывается конструктор. Когда объект больше не нужен, вызывается деструктор:
manager = FileManager('example.txt')
manager.write_data('Hello, world!')
# Когда объект manager больше не нужен, вызывается деструктор и файл закрываетсяPython использует механизм сборки мусора для автоматического управления памятью. Когда объект больше не используется (например, нет активных ссылок на него), сборщик мусора удаляет объект и вызывает его деструктор.
Точное время вызова деструктора зависит от работы сборщика мусора. Это означает, что нельзя гарантировать момент вызова деструктора. Поэтому для критических операций лучше использовать явное управление ресурсами, например, с помощью контекстных менеджеров (
with).Для явного управления ресурсами и их освобождения в предсказуемый момент лучше использовать контекстные менеджеры.
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Файл автоматически закрывается после выхода из блока withСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5