Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
GET — это HTTP-метод, который используется для запроса данных с сервера.
Когда ты открываешь веб-сайт или вводишь URL в браузере — это GET-запрос. Браузер запрашивает страницу у сервера, и сервер возвращает данные.
Когда ты заходишь на
https://example.com/users
, браузер отправляет: GET /users HTTP/1.1
Host: example.com
Ответ сервера
[
{"id": 1, "name": "Alice"},
{"id": 2, "name": "Bob"}
]
параметры передаются в строке запроса (например,
?id=123
). GET не изменяет данные на сервере.
браузеры и серверы могут сохранять результаты GET-запросов.
слишком длинные запросы могут не работать.
передача пароля в URL (
?password=123
) небезопасна. Если нужно передать параметры, они добавляются в URL:
GET /search?q=python&page=2
В Python можно отправить GET-запрос с помощью библиотеки
requests
import requests
response = requests.get("https://api.example.com/users", params={"id": 123})
print(response.json()) # Получаем ответ в JSON
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4
Бэкенд-разработчик должен разбираться в API, базах данных, серверных фреймворках, структурах данных, алгоритмах, принципах безопасности и DevOps-инструментах.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁11💊7👍3🤯2❤1
Блокировка (lock) — это механизм, который предотвращает одновременный доступ к данным разными транзакциями, чтобы избежать конфликтов, повреждения данных или "гонки" процессов.
Представь, что два человека редактируют один и тот же документ. Если они начнут менять его одновременно, файл может испортиться. Блокировки в БД работают так же — если один процесс изменяет данные, другой должен подождать, пока первый закончит.
предотвращает одновременные изменения одних и тех же строк.
когда два запроса пытаются изменить одно и то же значение.
разные операции не мешают друг другу.
Строчная (Row Lock) – блокирует только одну строку таблицы.
Табличная (Table Lock) – блокирует всю таблицу целиком.
Блокировка всей базы (Database Lock) – редко используется, но блокирует всю БД.
BEGIN;
SELECT * FROM users WHERE id = 1 FOR UPDATE; -- Блокирует строку, пока транзакция не завершится
Эксклюзивная (Exclusive, X-Lock) – блокирует запись для всех (никакие другие операции её не изменят).
Разделяемая (Shared, S-Lock) – блокирует только на запись (чтение возможно).
BEGIN;
UPDATE users SET balance = balance - 100 WHERE id = 1;
-- Пока транзакция не завершится, другая транзакция не сможет изменить balance пользователя 1.
Явные (ручные) – задаются программистом (
SELECT ... FOR UPDATE
). Неявные (автоматические) – создаются СУБД при
INSERT
, UPDATE
, DELETE
. Если два запроса ждут друг друга, система "зависает". Решение: правильный порядок выполнения транзакций.
Если транзакция не закрывается (
COMMIT
/ROLLBACK
), другие запросы ждут бесконечно. Решение: короткие транзакции, автоматическое завершение. Чем больше блокировок, тем медленнее работа БД.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
Разбить список (
list
) можно разными способами в зависимости от задачи: На части фиксированной длины
На N частей
По условию
Если нужно разделить список на подсписки длиной
n
, можно использовать list comprehensiondef split_list(lst, size):
return [lst[i:i + size] for i in range(0, len(lst), size)]
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(split_list(data, 3))
Вывод
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Если нужно разделить список на
N
частей, можно использовать numpy
или itertools
import numpy as np
def split_into_n_parts(lst, n):
return np.array_split(lst, n)
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(split_into_n_parts(data, 4))
Вывод
[array([1, 2, 3]), array([4, 5]), array([6, 7]), array([8, 9])]
Если нужно разделить список по какому-то критерию, например, на чётные и нечётные числа
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
even = [x for x in data if x % 2 == 0]
odd = [x for x in data if x % 2 != 0]
print(even, odd)
Вывод
[2, 4, 6, 8] [1, 3, 5, 7, 9]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12💊2😁1
Избавляться от дублирования стоит, если оно приводит к сложностям в поддержке, увеличению ошибок или нарушению принципа DRY. Однако если это уменьшает ясность, дублирование допустимо.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
В Python можно создать класс двумя основными способами:
Через
class
(обычный способ) Через
type()
(динамическое создание класса) Это стандартный способ, который мы используем чаще всего.
class Person:
def __init__(self, name):
self.name = name
def say_hello(self):
return f"Привет, я {self.name}!"
p = Person("Алиса")
print(p.say_hello()) # Привет, я Алиса!
Функция
type()
позволяет создать класс "на лету". Person = type("Person", (object,), {
"__init__": lambda self, name: setattr(self, "name", name),
"say_hello": lambda self: f"Привет, я {self.name}!"
})
p = Person("Боб")
print(p.say_hello()) # Привет, я Боб!
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍32
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
😁9💊4👍1🔥1
В Python счетчик ссылок (reference count) используется для управления памятью. Он показывает, сколько раз объект используется в программе. Когда счетчик ссылок падает до нуля, Python автоматически удаляет объект, освобождая память.
Python использует автоматическое управление памятью, основанное на подсчёте ссылок. Когда создаётся объект, Python хранит специальное число — количество ссылок на этот объект. Это число увеличивается, когда мы создаём новую ссылку на объект, и уменьшается, когда удаляем или перезаписываем переменную.
import sys
a = [1, 2, 3] # Создаём список
print(sys.getrefcount(a)) # Выведет 2 (одна ссылка 'a' + вызов getrefcount)
b = a # Новая ссылка на тот же объект
print(sys.getrefcount(a)) # Теперь 3 (a, b и сам getrefcount)
del a # Удаляем одну ссылку
print(sys.getrefcount(b)) # Теперь 2
del b # Удаляем последнюю ссылку, объект будет удалён из памяти
Python сам удаляет ненужные объекты, не давая памяти переполняться.
Если объект имеет циклические ссылки (например, список ссылается сам на себя), Python не может освободить его сразу, поэтому дополнительно используется сборщик мусора (Garbage Collector, GC).
import gc
class Node:
def __init__(self):
self.ref = self # Циклическая ссылка!
n = Node()
del n # Обычный подсчёт ссылок не сработает, объект останется в памяти
gc.collect() # Явный вызов сборщика мусора удалит его
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12😁7🔥3🤯2
Клиент-серверная архитектура – это модель взаимодействия устройств, где клиент запрашивает данные или услуги, а сервер их предоставляет.
Клиент – это программа или устройство, которое отправляет запросы (например, браузер).
Сервер – это программа или устройство, которое обрабатывает запросы и отправляет ответ (например, веб-сервер).
Сервер (сервер.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()
сервер.py
. Он ждёт подключения. клиент.py
. Клиент подключается к серверу и отправляет сообщение. Одноуровневая – клиент общается напрямую с сервером.
Двухуровневая – классическая схема "клиент сервер" (например, браузер веб-сервер).
Трёхуровневая – добавляется база данных (например, клиент сервер БД).
Многоуровневая – сложные распределённые системы с несколькими серверами (например, микросервисы).
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2
Это процесс изменения структуры базы данных. Для ее создания используется команда makemigrations, а для применения — migrate. Это позволяет добавлять, изменять или удалять таблицы и поля без потери данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Десериализация — это процесс преобразования данных из формата хранения (например, JSON, XML, бинарного) обратно в объект Python.
Клиент получает JSON-ответ от сервера и преобразует его в объекты.
Загружаем настройки программы из файла.
Данные хранятся в виде строк и извлекаются как объекты.
JSON (JavaScript Object Notation) — популярный формат хранения и передачи данных.
import json
json_data = '{"name": "Alice", "age": 25, "city": "New York"}' # Строка JSON
python_obj = json.loads(json_data) # Десериализуем в словарь
print(python_obj) # {'name': 'Alice', 'age': 25, 'city': 'New York'}
print(python_obj["name"]) # Alice
Pickle используется для хранения объектов Python в файлах или передаче их по сети.
import pickle
binary_data = b'\x80\x04\x95\x11\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x04name\x94\x8c\x05Alice\x94u.'
python_obj = pickle.loads(binary_data) # Десериализуем
print(python_obj) # {'name': 'Alice'}
Если данные хранятся в файле, их можно загрузить обратно в программу.
with open("data.json", "r") as file:
python_obj = json.load(file) # Загружаем JSON из файла
print(python_obj)
Pickle может содержать вредоносный код, так что никогда не десериализуйте неизвестные данные!
import pickle
pickle.loads(b"cos\nsystem\n(S'rm -rf /'\ntR.") # Опасная команда
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
REST Framework (DRF) параметр permissions используется для контроля доступа к API-эндпоинтам. Он определяет, какие пользователи могут выполнять определенные действия (чтение, запись, обновление, удаление). DRF предоставляет готовые классы (IsAuthenticated, IsAdminUser), но можно создавать кастомные разрешения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
BaseView
— это базовый класс представления (view) в Django, который предоставляет основу для создания представлений без жёсткой привязки к HTTP-методам (GET
, POST
и др.). Он является родительским классом для всех классов-представлений (CBV, Class-Based Views) в Django. Обеспечивает общую структуру для классов-представлений.
Разделяет логику обработки запроса и рендеринг.
Позволяет переопределять логику обработки запросов через
dispatch()
. Является родительским классом для
View
, TemplateView
, ListView
и других CBV. Этот класс сам по себе не обрабатывает запросы. Он лишь задаёт каркас для представлений.
from django.views import View
class BaseView:
def dispatch(self, request, *args, **kwargs):
"""Определяет, какой метод (GET, POST и т. д.) вызывать"""
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
return handler(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
"""Обработчик для неподдерживаемых HTTP-методов"""
return HttpResponseNotAllowed(self._allowed_methods())
Обычно мы используем
View
, который наследуется от BaseView
. from django.http import HttpResponse
from django.views import View
class MyView(View):
def get(self, request):
return HttpResponse("Это GET-запрос")
def post(self, request):
return HttpResponse("Это POST-запрос")
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Это механизм Django, позволяющий использовать числовые значения в моделях, сохраняя их читаемое представление. Например, вместо хранения строковых статусов ("pending", "approved") можно хранить числовые коды (1, 2), но работать с ними как с понятными именами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3❤2
Когда в проекте много файлов, могут возникать конфликты импортов. Python ищет модули в определённом порядке, и если несколько файлов имеют одинаковые имена или неправильные пути, может возникнуть ошибка.
Вместо
import mymodule # Может вызвать конфликт, если есть несколько файлов с таким именем
Лучше указывать полный путь в пакетах
from myproject.utils.mymodule import my_function
Если у вас есть файл
math.py
, импорт import math
будет загружать ваш файл, а не стандартный модуль math
из Python. - Не называйте файлы именами стандартных модулей:
math.py
, sys.py
, json.py
. - Проверьте, какой именно модуль загружается:
import math
print(math.__file__) # Путь к загруженному модулю
Если у вас есть структура
/myproject
/utils
mymodule.py
Решение
Добавьте пустой
__init__.py
в utils/
: /myproject
/utils
__init__.py # Делаем utils пакетом
mymodule.py
Теперь импорт будет работать
from utils import mymodule
Иногда Python не находит модуль, если он находится вне стандартных путей. Решение
Добавьте путь вручную:
import sys
sys.path.append("/path/to/directory")
import mymodule # Теперь импорт будет работать
Абсолютный импорт (рекомендуется)
from myproject.utils.mymodule import my_function
Относительный импорт (используется внутри пакетов):
from .mymodule import my_function
Если импорт не работает, проверьте, какие модули загружены и где Python ищет файлы
import sys
print(sys.modules.keys()) # Список загруженных модулей
print(sys.path) # Пути, где Python ищет модули
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10❤2
Это обобщенный контроллер в Django REST Framework, который объединяет CRUD-операции (Create, Retrieve, Update, Delete) в один класс. Он упрощает работу с API, автоматически обрабатывая маршруты и снижая дублирование кода.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2
Для реализации протокола итерирования данных в Python необходимо использовать два метода:
__iter__()
и __next__()
.Этот метод должен возвращать объект-итератор. В простом случае он возвращает сам объект, если объект реализует метод
__next__()
. Метод __iter__()
необходим для того, чтобы объект можно было использовать в конструкциях, которые требуют итерируемого объекта, таких как циклы for
. __next__()
Этот метод возвращает следующий элемент в последовательности. Когда элементы заканчиваются, метод должен вызвать исключение
StopIteration
для остановки итерации.class MyRange:
def __init__(self, start, end):
self.start = start
self.end = end
self.current = start
def __iter__(self):
self.current = self.start # Перезапуск итератора при каждом вызове
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
else:
self.current += 1
return self.current - 1
# Использование
for number in MyRange(1, 5):
print(number)
Для упрощения создания итераторов в Python можно использовать генераторы. Генераторы позволяют писать итераторы с использованием ключевого слова
yield
вместо определения методов __iter__()
и __next__()
вручную.def my_range(start, end):
current = start
while current < end:
yield current
current += 1
# Использование
for number in my_range(1, 5):
print(number)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8