Telegram Web Link
🧠 Как кэш CPU влияет на производительность кода на Python?

Лукас Аткинсон провёл эксперименты, чтобы выяснить, как поведение кэша процессора сказывается на времени выполнения кода на Python. Результаты оказались неожиданными.

🔍 Основные выводы:

- Последовательный доступ к спискам происходит быстрее, чем случайный
- При 200 тысячах элементов случайный доступ замедляется на 47%
- При 1.6 миллионах элементов — почти в 4 раза
- Python подвержен влиянию низкоуровневых аспектов памяти, включая кэш CPU

💡 Рекомендация: при работе с большими объёмами данных лучше использовать последовательный доступ — это действительно ускоряет код.

📖 Узнать больше: lukasatkinson.de (https://lukasatkinson.de/2024/python-cpu-caching/)

@Python_Community_ru
🖥 Важная особенность генераторов в Python!

Давайте разберемся, как это работает.

Что такое генератор?
Функция my_generator_function является генератором, поскольку использует ключевое слово yield.

В отличие от обычной функции, которая выполняет весь код и возвращает одно значение через return, генератор "приостанавливается" на каждом yield, возвращая указанное значение.

При следующем вызове он возобновляет работу с того места, где остановился.
Как работает yield?
Когда вы вызываете gen = my_generator_function(), код внутри функции не выполняется.

Создается специальный объект-генератор (gen).
Первый вызов next(gen) заставляет функцию выполниться до первого yield 1. Функция возвращает 1 и приостанавливается.
Второй вызов next(gen) возобновляет выполнение с точки после yield 1 и доходит до yield 2. Функция возвращает 2 и снова приостанавливается.
Именно поэтому print(next(gen), next(gen)) выводит 1 2.

Как работает return в генераторе?
Когда поток выполнения внутри генератора доходит до оператора return (в нашем случае return 73) или просто до конца функции без явного return, генератор считается завершенным.

Важно: значение, указанное в return (здесь 73), не возвращается как обычное значение через yield. Вместо этого генератор выбрасывает специальное исключение: StopIteration.

Этот механизм StopIteration является стандартным способом в Python сигнализировать, что итератор (а генератор - это тип итератора) исчерпан.

Перехват StopIteration и получение значения:
В правой части кода мы пытаемся вызвать next(gen) еще раз.

Генератор возобновляется после yield 2, доходит до return 73 и выбрасывает StopIteration.

Конструкция try...except StopIteration as err: перехватывает это исключение.

Ключевой момент: значение, указанное в операторе return генератора (73), становится доступным как атрибут .value пойманного исключения StopIteration.

Поэтому print(err.value) выводит 73.

Итог:
Return в генераторе не производит очередное значение, а завершает его работу. При этом значение из return "упаковывается" в исключение StopIteration, сигнализирующее об окончании, и его можно извлечь из атрибута .value этого исключения, если перехватить его вручную.

Стандартный цикл for item in generator(): в Python автоматически обрабатывает StopIteration (просто завершает цикл) и не дает прямого доступа к err.value. Поэтому для демонстрации этого механизма и получения возвращаемого значения используется явный вызов next() внутри блока try...except.

@Python_Community_ru
🌟 TARIFF — это инструмент, который вы действительно ждали, пакет для Python, который снова делает импорты "Великими".

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

✔️ Основные характеристики
Имитация тарифов на импорты: пользователь может установить "тарифы" (в процентах) на определённые пакеты, например:

```python
import tariff

tariff.set({
"numpy": 50, # 50% тариф на numpy
"pandas": 200, # 200% тариф на pandas
"requests": 150 # 150% тариф на requests
})
```

Замедление импорта: при импорте указанных пакетов время загрузки увеличивается пропорционально установленному тарифу.

Вывод сообщений: при каждом импорте с "обложенным тарифом" выводится сообщение в стиле политической риторики, например:

```plaintext
Только что введён 50% тариф на numpy! Исходный импорт занял 45000 мкс, теперь занимает 67500 мкс. Американские пакеты снова побеждают! #MIPA
```

Библиотека использует monkey-patching для перехвата и изменения процесса импорта.

Github (https://github.com/hxu296/tariff)

@ai_machinelearning_big_data

#fun #python

@Python_Community_ru
📌 Tracecat — это платформа с открытым исходным кодом для автоматизации безопасности. Проект предоставляет шаблоны в формате YAML для создания рабочих процессов с визуальным редактором, что упрощает автоматизацию рутинных задач.

Инструмент позволяет интегрировать Temporal для надежного выполнения сценариев и поддерживает MITRE D3FEND. Локальный запуск возможен с использованием Docker Compose, а для продакшена доступны конфигурации Terraform для AWS Fargate.

🤖 GitHub (https://github.com/TracecatHQ/tracecat)

@Python_Community_ru
This media is not supported in your browser
VIEW IN TELEGRAM
🖥 Новый фреймворк Function (fxn) компилирует Python-функции в нативный код с производительностью, сравнимой с Rust.

🧠 Как это работает?
- Используется символическое трассирование на CPython для анализа функций.
- Генерируется промежуточное представление (IR).
- IR транслируется в C++ или Rust, а затем компилируется в бинарный код.
- Поддерживаются платформы: Linux, Android, WebAssembly и другие.

📦 Пример:
@compile
def fma(x: float, y: float, z: float) -> float:
return x * y + z
После компиляции вы получаете нативный бинарный файл, который можно запускать без интерпретатора Python.

🔗 Подробнее (https://blog.fxn.ai/python-at-the-speed-of-rust/)
🔗 Github (https://github.com/olokobayusuf/)

#Python #Rust #fxn #Compiler #Performance #AI #ML #Wasm

@Python_Community_ru
🐍 Dulwich — это проект, который предоставляет альтернативу традиционным библиотекам, таким как GitPython и pygit2. Он полностью написан на Python и не требует наличия нативного Git.

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

🤖 GitHub (https://github.com/jelmer/dulwich)

@Python_Community_ru
🔍 Основные новшества в Django 5.2

1. 📦 Автоматический импорт моделей в интерактивной оболочке
Теперь при запуске команды python manage.py shell все модели из установленных приложений автоматически импортируются.

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

2. 🔗 Поддержка составных первичных ключей
Django 5.2 вводит нативную поддержку составных первичных ключей через класс CompositePrimaryKey. Это позволяет создавать таблицы с первичным ключом, состоящим из нескольких полей, без необходимости использования сторонних решений.

3. 🧩 Гибкая настройка BoundField в формах
Теперь можно переопределять класс BoundField на уровне проекта, формы или отдельного поля, устанавливая атрибут bound_field_class. Это дает разработчикам более тонкий контроль над отображением и поведением форм.

4. Расширенная асинхронная поддержка
Django продолжает развивать асинхронность, добавляя новые асинхронные методы и улучшая реализацию бэкендов аутентификации. Это особенно полезно для операций, связанных с вводом-выводом, и способствует созданию более производительных приложений.

5. 🎨 Новые виджеты форм и улучшения интерфейса
Добавлены новые виджеты форм, такие как ColorInput, SearchInput и TelInput, соответствующие стандартам HTML5. Также улучшена доступность форм для пользователей с особыми потребностями.

6. 🗃️ Улучшения в работе с базой данных
Поддержка изогнутых геометрий в GDAL, включая CurvePolygon, CompoundCurve, CircularString, MultiSurface и MultiCurve.

По умолчанию соединения с MySQL используют кодировку utf8mb4 вместо устаревшей utf8mb3.

Улучшена работа методов values() и values_list(), теперь они генерируют SELECT-запросы в указанном порядке.

🔧 Совместимость и поддержка
Django 5.2 поддерживает Python версий 3.10–3.13.

С выходом этой версии основная поддержка Django 5.1 завершена. Последний минорный релиз 5.1.8, также содержащий обновления безопасности, был выпущен одновременно с 5.2.

Django 5.0 достиг конца расширенной поддержки. Последний релиз безопасности, 5.0.14, также был выпущен сегодня. Рекомендуется обновиться до версии 5.1 или более новой.

📥 Обновление и ресурсы
Загрузить Django 5.2 можно с официальной страницы загрузки или через PyPI.

Полные примечания к релизу доступны в официальной документации.

Для автоматического обновления кода и устранения устаревших конструкций можно использовать инструмент django-upgrade.

Django 5.2 предлагает множество улучшений, направленных на упрощение разработки и повышение производительности приложений. Рекомендуется ознакомиться с новыми возможностями и планировать обновление своих проектов для использования всех преимуществ этой версии.

📌 Релиз (https://adamj.eu/tech/2025/04/07/django-whats-new-5.2/)

@Python_Community_ru
🐍 7 “бесполезных” функций Python, которые на самом деле полезны

Инструменты из стандартной библиотеки, которые могут удивить:

1. textwrap.dedent() — убирает отступы у многострочного текста.

import textwrap
text = textwrap.dedent(\"\"\"
Привет!
Это текст с отступами.
\"\"\").strip()
print(text)

2. difflib.get_close_matches() — находит схожие строки.

import difflib
words = ["python", "java", "javascript"]
print(difflib.get_close_matches("javascrip", words))

3. uuid.uuid4() — создает уникальный идентификатор.

import uuid
print(uuid.uuid4())

4. shutil.get_terminal_size() — определяет размеры терминала.

import shutil
columns, rows = shutil.get_terminal_size()
print(f"Размер терминала: {columns}x{rows}")

5. functools.lru_cache() — сохраняет результаты функции в кэше.

from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
print(fib(100))

6. itertools.groupby() — группирует элементы по ключу.

from itertools import groupby
data = [(&apos;fruit&apos;, &apos;apple&apos;), (&apos;fruit&apos;, &apos;banana&apos;), (&apos;veg&apos;, &apos;carrot&apos;)]
for key, group in groupby(data, lambda x: x[0]):
print(key, list(group))

7. contextlib.suppress() — элегантная альтернатива конструкции try-except.

from contextlib import suppress
with suppress(FileNotFoundError):
open("not_exist.txt")

@Python_Community_ru
🖥 less_slow.py (http://github.com/ashvardanian/less_slow.py) — Python, который не тормозит

Многие считают Python медленным, но это не всегда так. Ash Vardanyan в проекте Less Slow демонстрирует, как писать быстрый и эффективный код на Python — без магии, но с пониманием.

🐍 Что представлено в проекте:
🔹 pandas против polars — что быстрее при работе с миллионами строк
🔹 Использование Numba, Cython, PyO3, rust bindings
🔹 Работа с нативными типами, векторизация и zero-copy
🔹 Сериализация без проблем: сравнение MessagePack, Arrow, Parquet
🔹 Сравнение аллокаторов, подходов к I/O и нагрузочным тестам
🔹 Ускорение парсинга JSON: orjson, yyjson, simdjson, ujson
🔹 Как обойти GIL и не расплачиваться за удобство интерпретатора

📦 Библиотеки и техники:
Numba, Cython, cffi, maturin
simdjson, orjson, polars
pyarrow, msgspec, blosc2, memoryview
Работа с mmap, zero-copy, JIT-компиляция, py-spy, perf

📈 Кому это подойдет:
Тем, кто пишет ETL, пайплайны или ML/AI обработку
Кто работает с большими объемами данных или бинарными файлами
Кто хочет “оптимизировать до безобразия” и понять, как работает Python под капотом

В серии есть еще 2 интересных проекта:

🖥 less_slow.cpp — C++ без тормозов: ассемблер, кеши, SIMD, аллокации, парсинг JSON и трюки с памятью
👉 github.com/ashvardanian/less_slow.cpp

👣 less_slow.rs — продвинутый Rust: сравнение async/sync, SIMD, кеш-френдли структуры, быстрые сериализации
👉 github.com/ashvardanian/less_slow.rs

📚 Репозиторий (http://github.com/ashvardanian/less_slow.py):

💡 Даже если ты не используешь всё это каждый день, ты точно станешь писать лучший Python-код.

@Python_Community_ru
🔥 TeleGraphite — это быстрый и надежный скрапер публичных Telegram-каналов, написанный на Python.

Возможности:
- Извлечение постов из нескольких каналов в формате JSON (ID, текст, время, ссылки, почты, телефоны)
- Загрузка медиафайлов (фото, видео, документы)
- Удаление дубликатов
- Однократный режим (telegraphite once) и непрерывный (telegraphite continuous --interval)
- Фильтрация по ключевым словам и типу контента (текст/медиа)
- Планирование запусков по расписанию
- Настройка через CLI и YAML

Установка:
1) pip install telegraphite
2) Создать .env с API_ID и API_HASH
3) Список каналов в channels.txt

Репозиторий: https://github.com/hamodywe/telegram-scraper-TeleGraphite

@Python_Community_ru
🐍 Как легко создать мультисловарь (Multi-dictionary) в Python

Хотите, чтобы один ключ в словаре соответствовал нескольким значениям?

Это просто!

Используйте collections.defaultdict и встроенный list:

from collections import defaultdict

multidict = defaultdict(list)
multidict["SW"].append("Han Solo")
multidict["SW"].append("R2D2")

🔁 Теперь каждый ключ по умолчанию связан с пустым списком. А метод append добавляет новое значение в этот список.

Но будьте внимательны: это немного “обман”. На самом деле словарь по-прежнему отображает один ключ → одно значение. Просто это значение — список, в который вы сами добавляете что угодно.

Почему defaultdict удобен?
Потому что вам не нужно проверять, существует ли ключ в словаре. Пустой список будет создан автоматически при первом обращении к ключу.

@Python_Community_ru
🔥 Smolmodels (https://github.com/plexe-ai/smolmodels) — это библиотека на Python, которая позволяет создавать модели машинного обучения, описывая их поведение на естественном языке и используя минимум кода!

🔍 Основные возможности Smolmodels:

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

🌟 Построение модели: Метод model.build() принимает набор данных (существующий или сгенерированный) и создаёт множество возможных решений модели, обучая и оценивая их для выбора наилучшего.

🌟 Генерация данных и определение схемы: Библиотека может генерировать синтетические данные для обучения и тестирования, что полезно при отсутствии реальных данных или для дополнения существующих.

🔐 Лицензия: Apache-2.0

🖥 Github (https://github.com/plexe-ai/smolmodels)

@Python_Community_ru
🖥 ex — это инструмент для создания единого исполняемого файла .pex, который содержит всю вашу программу на Python и её зависимости. Это самодостаточная и переносимая среда выполнения, аналогичная virtualenv, но упакованная в один файл.

Зачем это нужно?

Простота развертывания: чтобы установить и запустить приложение, достаточно скопировать файл app.pex и запустить его — никакой дополнительной настройки.

Портируемость: один файл может включать сборки для разных платформ (Linux, macOS).

Изоляция зависимостей: все библиотеки (включая C‑расширения) уже находятся внутри, поэтому конфликтов версий нет.

Как пользоваться:

Устанавливаем сам инструмент:

pip install pex
Собираем .pex-файл:

pex requests -o fetch.pex --script=requests
После этого fetch.pex — это готовый исполняемый файл, который при запуске сразу импортирует и запускает библиотеку requests.

Интеграция с другими сборщиками:
Системы вроде Pants, Buck и {py}gradle могут автоматически собирать .pex-архивы из вашего кода.

Лицензия: Apache 2.0

GitHub: https://github.com/pex-tool/pex
Документация: https://docs.pex-tool.org/

@Python_Community_ru
🖥 Новая функция в Python 3.14: t-строки — типобезопасные f-строки

Python 3.14 вводит t"..." — новый синтаксис для строк, который ориентирован на безопасность типов и интеграцию с различными системами шаблонов, такими как SQL, HTML и другие.

🔹 Что такое t-строка?
t"..." — это как f"...", но:

- интерполяция ограничена и контролируется;
- поддерживается строгое соответствие шаблону;
- переменные можно передавать явно, что предотвращает SQL-инъекции и XSS.

🔸 Пример:

name = "Alice"
greeting = t"Hello, {name}!" # t-строка
Вместо немедленной подстановки, как в f"...", t"..." создает шаблон с выражениями в качестве параметров.

🔐 Зачем это нужно?
Обеспечение безопасности при генерации SQL, HTML, JSON

Улучшение инструментов и проверки типов (посредством статического анализа)

Контроль над контекстом исполнения (нельзя просто вставить переменную как есть — её нужно передать явно)

📦 Использование:
t-строки — это первый шаг к "template string literals", как в TypeScript.

Можно использовать с функциями:

def html(template: T[str]) -> SafeHTML:
...

html(t"{user_input}")

💡 Почему это важно?
Старый код:

f"SELECT * FROM users WHERE name = &apos;{user_name}&apos;"
может привести к SQL-инъекциям и XSS. t-строки являются безопасной альтернативой с встроенной защитой.

🛡 Пример: безопасный HTML

template = t"{user_input}"
html_output = html(template)
# <script>alert(&apos;bad&apos;)</script>

Функция html() может вернуть не просто строку, а полноценный HTMLElement. Больше никакой "грязи" — всё чисто и типобезопасно.

🔍 Работа с шаблоном
t-строки позволяют получить доступ к содержимому:

template = t"Hello {name}!"
template.strings # ("Hello ", "!")
template.values # (name,)
template.interpolations[0].format_spec # ">8"

Можно также вручную собрать шаблон:

Template("Hello ", Interpolation(value="World", expression="name"), "!")

🚀 Вывод:
t"..." — шаг к безопасным шаблонам и типизации строк в Python. Готовься к будущему Python — безопасному по умолчанию.

📌 Подробнее здесь (https://davepeck.org/2025/04/11/pythons-new-t-strings/)

@Python_Community_ru
This media is not supported in your browser
VIEW IN TELEGRAM
Zev 🔍

Это помощник для работы с терминалом на естественном языке.

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

pip install zev

📌 Github (https://github.com/dtnewman/zev)

@Python_Community_ru
🖥 PDF Craft — это библиотека на Python, предназначенная для преобразования PDF (в первую очередь сканированных книг) в Markdown и EPUB, с использованием локальных AI-моделей и LLM для структурирования содержимого.

🌟 Основные возможности:

- Извлечение текста и макета. Используется комбинация DocLayout-YOLO и собственных алгоритмов для обнаружения и фильтрации заголовков, колонтитулов, сносок и номеров страниц.

- Локальный OCR. Распознаёт текст на странице с помощью OnnxOCR и поддерживает ускорение на GPU (CUDA).

- Определение порядка чтения. С помощью layoutreader создаётся поток текста в том порядке, который воспринимает человек.

- Конвертация в Markdown. Генерирует .md с относительными ссылками на изображения (иллюстрации, таблицы, формулы) в папке assets.

- Конвертация в EPUB. На основе промежуточных результатов OCR передаёт данные в LLM (рекомендуется DeepSeek) для создания оглавления, глав, исправления ошибок и добавления аннотаций.

Установка и требования: Python версии 3.10 или выше (рекомендуется 3.10.16).

Используйте команды pip install pdf-craft и pip install onnxruntime==1.21.0 (или onnxruntime-gpu==1.21.0 для CUDA).

Для EPUB-конвейера необходим доступ к LLM-сервису (например, DeepSeek).

🟡 GitHub (https://github.com/oomol-lab/pdf-craft)

@Python_Community_ru
👾 FlexGet — это инструмент, который превращает рутинные задачи в автоматизированные рабочие процессы: от загрузки сериалов по RSS до организации медиатеки.

Модульная архитектура проекта особенно удобна. Базовый функционал включает более 150 плагинов для интеграции с qBittorrent, Plex и другими сервисами. При этом вся логика описывается с помощью декларативного подхода.

🤖 GitHub (https://github.com/Flexget/Flexget)

@Python_Community_ru
🔹 Тысяча гайдов для разработчиков в одном репозитории!

Разработчик из Твиттера собирал этот настоящий кладезь знаний целых 10 лет.

Внутри — буквально всё: от шпаргалок по горячим клавишам для ускорения работы до фундаментальных руководств по языкам программирования, веб-разработке, созданию ПО, сетям, безопасности и многому другому.

Что там есть:

📚 Инструменты для работы с CLI, GUI, вебом и локальными сетями.

📦 Списки всех актуальных фреймворков и библиотек 2025 года.

🛡 Гайды по тестированию и взлому приложений.

🔥 Шпаргалки по командной строке.

📰 Огромная подборка блогов, YouTube-каналов, онлайн-СМИ и журналов, чтобы быть в курсе и не терять хватку.

Фолиант знаний ждёт тебя!

📌 Github (https://github.com/trimstray/the-book-of-secret-knowledge?tab=readme-ov-file#manualshowtostutorials-toc)

@Python_Community_ru
🖥 Задача: "Кэширование и ленивые вычисления в многопоточном окружении"

🔜 Условие:

Вам необходимо создать декоратор @thread_safe_cached, который:

- Кэширует результат вызова функции по её аргументам (аналогично functools.lru_cache, но реализованный самостоятельно).
- Если несколько потоков одновременно вызывают функцию с одинаковыми аргументами:
- Только один поток фактически выполняет функцию,
- Остальные ждут, пока результат будет вычислен, и получают готовый результат.
- Кэш никогда не очищается (неограниченный размер).

Ограничения:

- Решение должно работать для любых функций и аргументов (должны быть хэшируемыми).
- Нельзя использовать готовый functools.lru_cache или другие библиотеки кэширования.
- Необходимо обеспечить корректную работу в многопоточной среде без гонок данных.

---

▪️ Подсказки:

- Для кэширования можно использовать словарь с ключами по аргументам (`*args`, `**kwargs`).
- Для защиты доступа к кэшу потребуется threading.Lock.
- Для ожидания завершения вычислений другими потоками можно применять threading.Event.
- Продумайте, как отличить "результат уже посчитан" от "результат в процессе вычисления".

---

▪️ Что оценивается:

- Умение работать с многопоточностью в Python.
- Правильная организация кэширования.
- Чистота и лаконичность кода.
- Умение обрабатывать тонкие случаи, например, одновременные вызовы.

---

▪️ Разбор возможного решения:

Основная идея:

- Создать кэш cache: Dict[Key, Result].
- Одновременно создать словарь "ожиданий" in_progress: Dict[Key, threading.Event].
- Если кто-то начал вычисление значения:
- Остальные ждут Event, пока он не будет установлен.

Пример реализации:

```python
import threading
import functools

def thread_safe_cached(func):
cache = {}
in_progress = {}
lock = threading.Lock()

@functools.wraps(func)
def wrapper(*args, **kwargs):
key = (args, frozenset(kwargs.items()))
with lock:
if key in cache:
return cache[key]
if key not in in_progress:
in_progress[key] = threading.Event()
in_progress[key].clear()
creator = True
else:
creator = False

if creator:
try:
result = func(*args, **kwargs)
with lock:
cache[key] = result
finally:
in_progress[key].set()
with lock:
del in_progress[key]
return result
else:
in_progress[key].wait()
with lock:
return cache[key]

return wrapper
```

---

▪️ Пояснения к коду:

- При первом вызове для новых аргументов поток создаёт Event и начинает вычислять результат.
- Остальные потоки видят Event и вызывают wait(), пока первый поток не установит set().
- Как только результат вычислен, Event сигнализирует всем ждущим потокам, что данные готовы.
- Доступ к cache и in_progress защищён через lock для предотвращения гонок.

---

▪️ Возможные подводные камни:

- Если не удалять Event из in_progress, кэш постепенно заполнится мусором.
- Если произойдёт ошибка внутри func, необходимо всё равно освободить Event, иначе потоки будут бесконечно ждать.
- Нельзя удерживать lock во время выполнения тяжёлой функции func, иначе все потоки будут блокироваться.

---

▪️ Вопросы на собеседовании по этой задаче:

- Как изменить реализацию, чтобы кэш имел ограничение по размеру (например, максимум 1000 элементов)?
- Как адаптировать декоратор под асинхронные функции (`async def`)?
- Что произойдет, если func иногда вызывает исключения? Как кэшировать ошибки или не кэшировать их?
- Как изменить реализацию так, чтобы кэш удалял устаревшие данные через TTL (Time-To-Live)?

@Python_Community_ru
2025/07/01 17:58:45
Back to Top
HTML Embed Code: