Python Community
12.9K subscribers
1.25K photos
38 videos
15 files
739 links
Python Community RU - СНГ сообщество Python-разработчиков

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

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

РКН реестр:
https://knd.gov.ru/license?id=67847dd98e552d6b54a511ed&registryType=bloggersPermission
Download Telegram
🖥 Что выведет код ниже?


def append_to_list(val, my_list=[]):
my_list.append(val)
return my_list

print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))


🤯 Подвох
Многие думают, что каждый вызов append_to_list() создаёт новый список, и ожидают вывод:


[1]
[2]
[3]

Но на самом деле Python выведет:


[1]
[1, 2]
[1, 2, 3]

🧠 Почему так происходит?
В Python значения аргументов по умолчанию вычисляются один раз — при определении функции, а не при каждом вызове.

Значение my_list=[] создаётся один раз и сохраняется между вызовами. Это работает как статическая переменная внутри функции.

Как это исправить?
Используй None как значение по умолчанию:


def append_to_list(val, my_list=None):
if my_list is None:
my_list = []
my_list.append(val)
return my_list

print(append_to_list(1)) # [1]
print(append_to_list(2)) # [2]
print(append_to_list(3)) # [3]

💡 Вывод
Не используйте изменяемые объекты (например, list, dict, set) как значения по умолчанию для аргументов функций в Python.




@Python_Community_ru
🐍 dlt — библиотека для загрузки данных на Python. Этот open-source инструмент упрощает работу с данными — от простых скриптов до сложных ETL-пайплайнов. Автоматически определяет структуру данных и адаптируется под разные источники и хранилища.

Проект удобен для быстрого прототипирования: можно начать в Colab-ноутбуке, а затем масштабировать до production-решения. Поддерживает инкрементальную загрузку и интеграцию с Airflow.

🤖 GitHub (https://github.com/dlt-hub/dlt)



@Python_Community_ru
🖥 Полезный трюк в Python: как отсортировать список по нескольким условиям одновременно

Если вы хотите отсортировать список объектов (например, словарей или кортежей) сразу по нескольким критериям — например, сначала по возрасту по возрастанию, а затем по имени по убыванию — не нужно писать громоздкие функции.

Используйте sorted() с key, комбинируя несколько полей с нужной логикой сортировки. Вот как:


people = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 25},
{"name": "David", "age": 30},
]

# Сортировка: сначала по age (по возрастанию), затем по name (по убыванию)
sorted_people = sorted(people, key=lambda p: (p["age"], -ord(p["name"][0])))

for person in sorted_people:
print(person)


💡 Работает и с объектами, и с кортежами — главное, правильно составить key. Особенно полезно для фильтрации списков в табличных данных, при выводе результатов или генерации отчётов.

#python

Больше коротких уроков тут (https://www.youtube.com/shorts/VFmdZOYI8qc)

@Python_Community_ru
🐧 Pynguin — генератор юнит-тестов для Python. Инструмент автоматически создаёт тесты для Python-кода, экономя время разработчиков и при этом адаптирован под особенности динамической типизации Python.

Проект пока находится в стадии исследования и требует осторожности — он исполняет тестируемый код, поэтому разработчики рекомендуют использовать изолированные среды вроде Docker. Установка через pip install pynguin, минимальная конфигурация требует указания пути к проекту и модулям для тестирования.

🤖 GitHub (https://github.com/se2p/pynguin)



@Python_Community_ru
👍2
🐍 Python Gotcha: как правильно логировать необработанные исключения

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

Пример кода:

import logging

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.FileHandler("app.log")
handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s"))
logger.addHandler(handler)

def divide(a, b):
return a / b

def main():
logger.info("Start")
logger.info(divide(10, 0)) # ZeroDivisionError
logger.info("End")

if __name__ == "__main__":
main()


📄 В логе:



2025-07-24 12:00:00 __main__ INFO Start

А сам ZeroDivisionError — только в консоли. Лог молчит.

Решение — использовать sys.excepthook:


import sys

def handle_uncaught_exception(exc_type, exc_value, exc_traceback):
logger.critical("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = handle_uncaught_exception

Теперь, если произойдёт ошибка, она попадёт в лог:



CRITICAL Uncaught exception
Traceback (most recent call last):
...
ZeroDivisionError: division by zero

📌 Вывод:
— Необработанные исключения не попадут в лог, если явно не подключить sys.excepthook
— Это особенно важно в продакшене: лог покажет, где и почему всё сломалось
— Просто и надёжно

🔗 Подробнее (https://andrewwegner.com/python-gotcha-logging-uncaught-exception.html)



@Python_Community_ru
📦 Гайд: “The Step-by-Step Guide to Python Packaging Tools 2025”

Python-инфраструктура сильно изменилась.

Выбор между pip, poetry, uv, hatch, pdm и др. — это уже не просто "pip install", а стратегическое решение.

В этом гайде сравниваются 6 ключевых инструментов, каждый со своими сильными и слабыми сторонами:

1️⃣ uv — самый быстрый и универсальный (написан на Rust)
До 100× быстрее pip
Объединяет pip, virtualenv и pip-tools
Поддержка PyPI-паблишинга и Python-менеджмента
📌 Выбор для CI/CD и monorepo-проектов

2️⃣ Poetry 2 — стандарт для библиотек и модульных приложений
Поддержка semantic versioning, lock-файлов, плагинов
Отлично подходит для open source
📌 Идеален для reproducible builds и PyPI

3️⃣ Hatch — “Cargo для Python”
Поддержка матриц окружений, monorepo, хуков
Интеграция с uv для скорости
📌 Выбор для сложных enterprise-проектов и тестовых фреймворков

4️⃣ PDM — стандартизированный менеджер без virtualenv
Поддержка PEP 582 (__pypackages__), PEP 621
Изоляция без виртуалок, удобен для прототипов
📌 Подходит для rapid dev и экспериментальных сборок

5️⃣ Pipenv — простой интерфейс для приложений
Pipfile, auto-venv, чистый CLI
📌 Хорош для небольших проектов и начинающих

6️⃣ pip — классика
Совместим везде, гибкий
Нет lock-файлов, окружений, требует внешних тулов
📌 Решение для легаси-проектов или скриптов

💡 Выводы:

• uv — лучший выбор для скорости, CI и автоматизации
• Poetry — стандарт для библиотек, особенно с open source
• Hatch — для сложных проектов и продвинутых пайплайнов
• PDM — для быстрой разработки и современных стандартов
• Pipenv — простой, но морально устарел
• pip — базовый минимум, но требует ручной сборки обвязки

Если ты:
🔹 Собираешь ML‑пайплайн → смотри в сторону uv + Hatch
🔹 Работаешь над библиотекой → Poetry 2 будет логичным выбором
🔹 Строишь монорепу или сложный фреймворк → Hatch + workspace
🔹 Пишешь простые скрипты или MVP → подойдёт PDM или Pipenv

🔗 Полный гайд (https://www.datumlabs.io/resources/the-step-by-step-guide-to-python-packaging-tools-2025)



@Python_Community_ru
This media is not supported in your browser
VIEW IN TELEGRAM
🧹 ObjectClear — инструмент для удаления объектов с изображений с помощью ИИ

Что умеет:
🖼 Загружаешь изображение
🎯 Выделяешь объект, который хочешь убрать
Модель автоматически удаляет его и восстанавливает фон

Под капотом:
— Segment Anything (SAM) от Meta для выделения объекта
— Inpaint-Anything для генерации фона
— Поддержка работы в браузере (Gradio UI)

Можно запускать локально. Всё open-source.

📎 GitHub: https://github.com/zjx0101/ObjectClear



@Python_Community_ru
🔥 Нашёл 100% open-source AI-агента для задач в разработке ПО!

ByteDance выпустили Trae Agent — LLM-агент для автоматизации задач в области программной инженерии.

Планирование и использование инструментов из коробки
Умеет рефакторить, дебажить, разбираться в коде
Полностью автономный
Абсолютно открытый код

Отличная база, если вы строите что-то с AI.

git clone https://github.com/bytedance/trae-agent.git
cd trae-agent
uv venv
uv sync --all-extras

https://github.com/bytedance/trae-agent



@Python_Community_ru
🖥 Контекстный перехват stdout — как легко отключить или сохранить print

💡 Хотите, чтобы print() не мешал логике и при этом легко отключался или сохранялся в файл?

Вместо того чтобы комментировать все print() в проде, подмените стандартный вывод через контекстный менеджер — и легко направляйте вывод в файл, /dev/null или даже буфер для последующей обработки.

Это особенно полезно при отладке в прод-среде или при генерации логов без сторонних библиотек.


import sys
from contextlib import contextmanager
from io import StringIO
import os

@contextmanager
def capture_stdout(to_file=None, suppress=False):
original_stdout = sys.stdout
try:
if suppress:
sys.stdout = open(os.devnull, 'w')
elif to_file:
sys.stdout = open(to_file, 'w')
else:
buffer = StringIO()
sys.stdout = buffer
yield sys.stdout
finally:
sys.stdout.close() if sys.stdout not in (original_stdout, sys.__stdout__) else None
sys.stdout = original_stdout

# Пример использования:
with capture_stdout(suppress=True):
print("Этого вы не увидите")

with capture_stdout(to_file="output.log"):
print("А это уйдёт в файл")

with capture_stdout() as captured:
print("Это записано во внутренний буфер")

print("Буфер содержит:", captured.getvalue().strip())




@Python_Community_ru
This media is not supported in your browser
VIEW IN TELEGRAM
🌐 BrowserOS — операционная система внутри браузера на базе AI

BrowserOS — это экспериментальный проект, превращающий браузер в полноценную AI‑среду с "живущими" агентами. По сути, это OS-слой внутри вкладки браузера, где ИИ-агенты могут взаимодействовать с интерфейсами как пользователи.

🧠 Основные идеи:
— Агент может кликать, печатать, читать и взаимодействовать с окнами внутри браузера
— Поддержка многозадачности: можно открыть несколько окон, как в реальной ОС
— Простое API для создания интерфейсов и запуска ИИ-агентов
— Можно подключать LLM и наделять их возможностью выполнять действия

📦 Особенности:
— UI построен на React
— Использует WebAssembly и Web Workers
— Позволяет тестировать и запускать агента в контролируемой "песочнице"

💡 Подходит для:
— Исследований в области AI-агентов
— Прототипирования мультимодальных систем
— Демонстрации взаимодействия LLM с интерфейсами

🔗 GitHub (https://github.com/browseros-ai/BrowserOS)



@Python_Community_ru
This media is not supported in your browser
VIEW IN TELEGRAM
🖥 Хочешь узнать, какие библиотеки в твоём Python‑проекте реально используются?

Многие проекты тянут за собой ненужные зависимости, особенно после десятков итераций.

С помощью vulture ты можешь найти неиспользуемый код и импорты — и легко вычистить проект от мусора.



Установка vulture
pip install vulture

Поиск неиспользуемого кода и импортов
vulture your_project/ > unused.txt

Пример: посмотреть, что не используется
cat unused.txt




@Python_Community_ru
🔥4
🔥 WaterCrawl — продвинутая платформа для веб-краулинга и подготовки данных под LLM

Если нужно собрать и структурировать контент с сайтов для ИИ — это мощный инструмент.

🧠 В основе:
— Django + Scrapy + Celery
— Асинхронный краулинг, API и UI
— Скриншоты, PDF, JS-рендер, SSE

🚀 Возможности:
— Быстрый запуск через Docker (`docker compose up`)
— Интеграции с Dify, n8n, Langflow
— Пакетная отправка запросов через REST API
— SDK для Python, Go, Node, PHP

⚙️ Репозитории (https://github.com/watercrawl/WaterCrawl)



@Python_Community_ru
🆕 В pyfonts — мощное обновление!

Теперь можно задать глобальный шрифт по умолчанию — и он применится ко всем текстам автоматически.
Больше не нужно вручную проставлять font в каждом элементе 🎯

Идеально для проектов с единой визуальной стилистикой — экономит кучу времени и кода.

🔥 Фичу реализовал John Gardner — спасибо!

Ждём фидбек, звёзды и предложения

📦 GitHub: http://github.com/JosephBARBIERDARNAL/pyfonts



@Python_Community_ru
Чтобы получить все уникальные пары элементов из списка, вовсе не обязательно писать громоздкие вложенные циклы. Python предоставляет модуль itertools, который содержит готовые инструменты для таких задач.

Например, для списка features = ['price', 'size', 'rating'] можно написать так:


from itertools import combinations

pairs = list(combinations(features, 2))
print(pairs) # [('price', 'size'), ('price', 'rating'), ('size', 'rating')]

Функция combinations берёт на вход итерируемый объект и размер комбинации.

В нашем случае размер равен 2, поэтому мы получаем все возможные неупорядоченные пары без повторов.

Это решение не только короче, но и легче читается. Пользуйтесь библиотекой itertools, чтобы избавляться от рутины и писать более чистый код!



@Python_Community_ru
👍3