Python Community
11.9K subscribers
1.4K photos
115 videos
15 files
921 links
Python Community RU - СНГ сообщество Python-разработчиков

Чат канала: @python_community_chat

Сотрудничество: @cyberJohnny и @Sergey_bzd

РКН реестр:
https://knd.gov.ru/license?id=67847dd98e552d6b54a511ed&registryType=bloggersPermission
Download Telegram
🔌 python-kasa — это библиотека для управления умными устройствами TP-Link с помощью Python.

Если у вас есть умные розетки, лампы или другие устройства TP-Link и вы хотите их автоматизировать через Python, стоит обратить внимание на эту библиотеку. С её помощью можно легко включать и выключать устройства, проверять их статус и даже управлять ими через командную строку. Поддерживаются как модели Kasa, так и Tapo, включая розетки, выключатели, лампы и даже камеры.

🤖 GitHub (https://github.com/python-kasa/python-kasa)
@Python_Community_ru
🚀 Как Duolingo удалось увеличить производительность микросервисов на 40% с помощью асинхронного Python 🐍

Duolingo поделилась тем, как им удалось существенно улучшить эффективность своих Python-сервисов, перейдя на использование async/await, и сделали это не ради моды, а для снижения затрат.

💸 Мотивация: повышение производительности и уменьшение расходов
Duolingo управляет множеством микросервисов, которые обрабатывают большие объемы трафика. Несмотря на высокую нагрузку, многие их Python-сервисы простаивали в ожидании ввода-вывода — например, при сетевых запросах или взаимодействии с базой данных. Это приводило к неэффективному использованию процессора, и, соответственно, деньги на облачный хостинг расходовались впустую.

Асинхронный код — это способ “переключаться” между задачами во время ожидания, что позволяет более эффективно использовать процессор. Именно это и стало главной мотивацией: не просто стать асинхронными, а сократить расходы.

⚙️ Как проходила миграция
Процесс был постепенным и тщательно продуманным. Вот ключевые шаги:

Переход не “всё или ничего”
Команда не начала с переписывания всего сервиса с нуля. Они начали с изменения отдельных маршрутов на async def, добавляя асинхронность по частям.

Постепенная адаптация инструментов
Пришлось обновить библиотеки и инструменты внутри компании:
HTTP-клиент переписали с использованием aiohttp,
систему аутентификации адаптировали к async-контекстам,
обновили логирование, трассировку и метрики для работы с async-архитектурой.

Тестирование и инфраструктура
Асинхронные изменения потребовали пересмотра тестов. Они внедрили поддержку pytest-asyncio и переосмыслили подход к мокам и фикстурам.

Постепенный запуск в продакшене
Сначала маршруты работали в синхронном режиме. Затем их перевели в асинхронный режим и замерили разницу. Это помогло выявить “узкие места” до массового внедрения.

📈 Результаты: +40% производительности на экземпляр
Эффективнее стал использоваться процессор у каждого экземпляра микросервиса.
Уменьшилось среднее время ответа (latency).
Снизилось количество необходимых экземпляров — экономия в деньгах.
Код стал легче масштабировать и поддерживать в среде с высокой интенсивностью ввода-вывода.

Пока один запрос “ждет”, процессор может выполнять другие задачи.

🔍 Выводы
Duolingo подчеркивает:
асинхронность не нужна “просто потому что это модно”.
Но если у вас сервис с большим числом операций ввода-вывода и важна производительность — асинхронный Python может обеспечить реальный прирост и экономию.

Оригинальный пост (https://blog.duolingo.com/async-python-migration/)

@Python_Community_ru
🔥2
🧠 Задача на внимание и знание подводных камней в Python

Что выведет данный код?

def make_funcs():
funcs = []
for i in range(3):
def wrapper(x=i):
return lambda: x
funcs.append(wrapper())
return funcs

a, b, c = make_funcs()
print(a(), b(), c())

Варианты ответа:

A) 0 1 2
B) 2 2 2
C) 0 0 0
D) Ошибка на этапе выполнения

Ответ: 0 1 2

📘 Объяснение:
🔹 Цикл for i in range(3) проходит по значениям 0, 1, 2.

🔹 В каждой итерации вызывается wrapper(x=i) — это копирует текущее значение i в локальную переменную x.

🔹 Затем возвращается lambda: x, которая запоминает это конкретное значение x.

🔹 В итоге:

a() → 0

b() → 1

c() → 2

Если бы мы не использовали x=i по умолчанию, а написали просто lambda: i, все функции замкнули бы одну и ту же переменную i, и на момент вызова она бы уже была равна 3.

@Python_Community_ru
🐍 Задача по Python: Замыкания и области видимости

Что покажет следующий код?


def outer():
x = 5
def inner():
nonlocal x
x += 1
return x
return inner

f = outer()
print(f())
print(f())
print(f())


Варианты ответа:
A)

7
8


B)

5
5


C)

6
6


D) Ошибка выполнения

---

Правильный ответ: A

Почему:
Функция outer создаёт замыкание. Переменная x сохраняется между вызовами f, так как inner замыкает x и изменяет её с помощью nonlocal. Это классический пример использования замыканий в Python.

@Python_Community_ru
👍1
Строковый метод translate позволяет заменять или удалять несколько символов в строке за один раз. Это похоже на множественные вызовы метода replace.

```python
import string

s = "Hello, world!"
print(s.translate(str.maketrans("", "", string.punctuation)))
# Hello world
```

Метод translate ожидает «таблицу перевода», которую мы создаем с помощью вспомогательного метода класса maketrans.

Третий аргумент (string.punctuation в примере) — это строка символов, которые мы хотим удалить.

Значение string.punctuation включает в себя следующие символы:
!#$%&'()*+,-./:;?@[\]^_{|}~`

Суть шпаргалки заключается в том, что она демонстрирует, как эффективно удалить все стандартные знаки препинания из строки в Python, используя комбинацию методов str.maketrans для создания инструкции по удалению и str.translate для применения этой инструкции к строке.

@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
📌 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
👍1🤔1
😂 Жиза



@Python_Community_ru
👍3🔥3
🔥 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