Zen of Python
Полный Дзен Пайтона в одном канале Разместить рекламу: @tproger_sales_bot Правила общения: https://tprg.ru/rules Другие каналы: @tproger_channels Сайт: https://tprg.ru/site Регистрация в перечне РКН: https://tprg.ru/xZOL
Показати більше📈 Аналітичний огляд Telegram-каналу Zen of Python
Канал Zen of Python (@zen_of_python) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 19 289 підписників, посідаючи 6 972 місце в категорії Технології та додатки та 35 079 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 19 289 підписників.
За останніми даними від 05 червня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на 26, а за останні 24 години на -3, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 12.34%. Протягом перших 24 годин після публікації контент зазвичай збирає 5.62% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 2 378 переглядів. Протягом першої доби публікація в середньому набирає 1 082 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 9.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як github, rust, pip, api, install.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Полный Дзен Пайтона в одном канале
Разместить рекламу: @tproger_sales_bot
Правила общения: https://tprg.ru/rules
Другие каналы: @tproger_channels
Сайт: https://tprg.ru/site
Регистрация в перечне РКН: https://tprg.ru/xZOL”
Завдяки високій частоті оновлень (останні дані отримано 07 червня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
pip — это менеджер пакетов по умолчанию для Python 2 / 3 (где «двойка» не установлена;
pip3 — это явно указанный менеджер пакетов для Python 3.
Если у тебя установлен только Python 3, pip и pip3 будут работать одинаково.
Как проверить, какая версия связана с pip
pip --version # pip 20.0.2 from /usr/lib/python2.7/site-packages/pip (python 2.7)
pip3 --version # pip3 21.2.4 from /usr/lib/python3.8/site-packages/pip (python 3.8)
#основы
@zen_of_pythonTypedDict («Типизированный словарь»). В этом посте разберём, зачем нужен, как правильно использовать и какие возможности открывает.
TypedDict — это специальный тип данных, что позволяет создавать словари с явно заданными типами для ключей и значений. Таким образом, вы можете описать структуру словаря, как будто это объект с фиксированными полями.
from typing import TypedDict
class User(TypedDict):
name: str
age: int
email: str
В обычных словарях Python ключи и значения могут быть абсолютно любыми, и это даёт большую гибкость, но вместе с тем усложняет контроль и проверку данных. TypedDict позволяет добавить статическую типизацию к словарям, тем самым снизить вероятность неожиданных ситуаций с вашими экземплярами.
В примере выше мы создаем класс User, который наследуется от TypedDict. Теперь словари типа User должны иметь ключи name, age и email с типами str, int и str соответственно.
Теперь при создании экземпляра:
user: User = {
"name": "Alice",
"age": 30,
"email": "alice@example.com"
}
если в словаре отсутствует обязательный ключ или тип значения не совпадает, современные инструменты статической типизации (например, mypy) выдадут ворнинг.
Опциональные ключи
Бывает, что не всегда все ключи словаря на месте. В TypedDict их можно сделать необязательными (total=False):
class User(TypedDict, total=False):
nickname: str
bio: str
#основы
@zen_of_pythonst.navigation(position="top");
— поддерживается темная тема через st.context.theme;
— большинство виджетов и элементов теперь поддерживают параметр ширины width;
— добавлена настройка CORS для разрешённых источников;
— в сообщениях об ошибках появился удобный копипаст-кнопка;
— теперь можно запускать сервер Streamlit на порту 3000 без дополнительных настроек;
— добавлена поддержка форматов номеров для колонок с числами и прогрессбаров.
Release Note
#инструмент
@zen_of_python
🫡 — Если отдаю честь за такую работу
a = {"x": 1, "y": 2}
b = {"y": 2, "x": 1}
a == b # True
То есть, равенство проверяется по парам ключ‑значение, а не по их порядку (в отличие от списка).
Почему обычный dict сравнивается по содержанию, а не по порядку?
— Оптимизация: словари предназначены для быстрой работы по ключу (хэширование);
— Благодаря «разделённой таблице» (split-table) в реализации CPython, словарь может одновременно эффективно хранить и порядке вставки, и хэш-структуру.
#основы
👌 — Если всё по красоте
class UsedDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._used_keys = set()
def __getitem__(self, key):
self._used_keys.add(key)
return super().__getitem__(key)
def get_unused_keys(self):
return set(self.keys()) - self._used_keys
— Наследуемся от стандартного dict, чтобы сохранить привычный интерфейс;
— При инициализации создаём пустое множество _used_keys, в котором будем хранить все ключи, к которым обращались;
— Переопределяем метод __getitem__, который вызывается при чтении значения по ключу mydict[key]. В этом методе сначала отмечаем ключ как использованный, а затем возвращаем значение;
— Добавляем метод get_unused_keys, который возвращает разницу между всеми ключами словаря и теми, которые использовались.
Пример использования:
config = UsedDict({
"host": "localhost",
"port": 8080,
"debug": True,
"timeout": 30
})
print(config["host"]) # используется
print(config["port"]) # используется
unused = config.get_unused_keys()
print("Неиспользованные ключи:", unused)
# Выведет: Неиспользованные ключи: {'debug', 'timeout'}
#основыyoutube-search
2. MCP-сервер — оборачивает этот модуль и превращает его в доступный инструмент для LLM.
def search_youtube(query, max_results):
# Используем youtube_search
...
return result_dict
И MCP-сервер, использующий этот модуль:
from fast_mcp import FastMCP
server = FastMCP(name="videos")
server.add_tool("get_videos", search_youtube)
LLM теперь может вызывать get_videos(), передав строку запроса — и получить отформатированный список роликов.
Автогенерация MCP из FastAPI
Если ваш API уже на FastAPI, вы можете автоматически создать MCP-интерфейс через fast_mcp.
from fast_mcp.contrib.fastapi import convert_app_to_mcp
app = FastAPI()
# ... API endpoints
mcp_server = convert_app_to_mcp(app)
Но это подойдёт, если вы точно знаете, что API и MCP будут едины и не потребуется различать их архитектурно.
Где это уже используется?
Пример из видео — интеграция с Claude Desktop, где в конфигурации можно указать локальный MCP-сервер:
{
"name": "YouTube Videos",
"command": "uv",
"args": {
"dir": "~/youtube_service",
"file": "run_mcp.py"
}
}
#LLMINSERT, и вроде всё просто. Нет ошибок. Но и данные не вставлены. Звучит странно? Такое действительно может случиться с PostgreSQL — и случается чаще, чем хотелось бы.
Как можно вставить данные и не вставить одновременно?
Когда INSERT не срабатывает, первое, что приходит в голову — ошибка. Но PostgreSQL умеет «глотать» такое — ведь вы сами его об этом попросили.
Виновник — ON CONFLICT DO NOTHING
INSERT INTO users (id, email)
VALUES (42, 'user@example.com')
ON CONFLICT (id) DO NOTHING;
Здесь мы явно говорим: "если произойдёт конфликт по id, ничего не делай". И PostgreSQL по умолчанию так и поступает.
Поведение UPSERT при множественных уникальных индекса
Представьте, что в таблице есть не один, а два уникальных индекса:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE,
username TEXT UNIQUE
);
Теперь вы выполняете:
INSERT INTO users (email, username)
VALUES ('user@example.com', 'johnny');
А если username = 'johnny' уже существует, но email ещё нет?
Вставка завершится ошибкой!
Так происходит, потому что ON CONFLICT (email) говорит PostgreSQL: «молчи, если конфликт по email, но бросай ошибку, если конфликт по чему-то ещё».
Чтобы избежать этого, используем:
ON CONFLICT DO NOTHING
Тогда PostgreSQL проигнорирует конфликт по любому индексу. Но это может спровоцировать проблемы, особенно при вставке пачкой
Как отладить такую ситуацию?
— Проверяйте rowcount после запроса. В Python/psycopg2, например:
cursor.execute(sql, values)
if cursor.rowcount == 0:
print("Nothing inserted!")
— Добавьте RETURNING и логируйте:
INSERT INTO users (email, username)
VALUES ('user@example.com', 'johnny')
ON CONFLICT DO NOTHING
RETURNING id;
Если возвращается пустой результат — значит, вставки не было.
— Логируйте причину. Если вы используете логику вида DO UPDATE, можно добавить логи в `UPDATE`-часть или сохранять «причину отказа» отдельно.
#sql
Вже доступно! Дослідження Telegram за 2025 — головні інсайти року 
