Ghostly Python
9.03K subscribers
535 photos
24 videos
599 links
Погружаемся в мир Python: задачи, фишки, библиотеки и террабайты полезного материала.

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

Цены: @heywan_media

Реклама на бирже: https://telega.in/c/+IOa15XDNbxRkYzNi
Download Telegram
Please open Telegram to view this post
VIEW IN TELEGRAM
😁29👍32
👩‍💻 Работа с CSV на Python с помощью csv

csv — встроенный модуль для чтения и записи табличных данных. Подходит для обмена данными с Excel/Google Sheets, логов и простых отчётов.

⚙️ Пример: чтение, фильтрация и запись CSV одним скриптом

import csv
from pathlib import Path

# Создадим входной CSV с заголовками
src = Path("employees.csv")
with src.open("w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "role", "salary"])
writer.writeheader()
writer.writerows([
{"name": "Alice", "role": "Engineer", "salary": "120000"},
{"name": "Bob", "role": "Manager", "salary": "135000"},
{"name": "Cara", "role": "Engineer", "salary": "125000"},
])

# Читаем и фильтруем инженеров с зарплатой > 120k
rows = []
with src.open("r", encoding="utf-8", newline="") as f:
reader = csv.DictReader(f)
for row in reader:
row["salary"] = int(row["salary"]) # приведение типов
if row["role"] == "Engineer" and row["salary"] > 120000:
rows.append(row)

# Сохраняем результат в новый CSV
dst = Path("top_engineers.csv")
with dst.open("w", encoding="utf-8", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["name", "role", "salary"])
writer.writeheader()
writer.writerows(rows)

print(f"Сохранено: {dst} ({len(rows)} записей)")


💬 Как это работает:

🟢 csv.DictReader/DictWriter работает со словарями по именам колонок — удобнее, чем позиционные индексы.
🟢 newline="" при открытии файла важно для корректных переводов строк на Windows.
🟢 Поля приходят как строки — приводите типы вручную (например, int для чисел).
🟢 Для особых форматов используйте параметры: delimiter=";", quotechar='"', quoting=csv.QUOTE_MINIMAL

🐍 Ghostly Python | #гайды
Please open Telegram to view this post
VIEW IN TELEGRAM
👩‍💻 Самый быстрый способ читать Excel в Python

В статье результаты тестирования pandas, openpyxl, Tablib, DuckDB, LibreOffice и даже связки с Rust. Кто справился лучше всех и как за 4 секунды Python «проглотил» полмиллиона строк.

➡️ Ссылка на статью

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤯1
Вопрос с собеса

Зачем нужен __slots__ в Python и какие у него подводные камни?

Пример🔽
class Point:
__slots__ = ("x", "y") # фиксируем набор атрибутов

def __init__(self, x, y):
self.x, self.y = x, y

p = Point(1, 2)
print(hasattr(p, "__dict__")) # ➔ False (нет словаря экземпляра)
p.z = 3 # ➔ AttributeError: 'Point' object has no attribute 'z'


Ответ🔽
__slots__ отключает создание __dict__ у экземпляров и фиксирует набор допустимых атрибутов. Это сокращает память (особенно важно для миллионов объектов) и может ускорять доступ к полям. Обратная сторона — нельзя динамически добавлять новые атрибуты, а некоторые механики требуют дополнительных слотов.

🟢 Запомнить:

Используйте __slots__, когда класс создаёт много экземпляров с стабильным набором полей.

Для поддержки weakref добавьте '__weakref__' в __slots__.

В иерархиях все классы должны быть «кооперативны»: у подклассов тоже задавайте __slots__ (или потеряете выгоды/совместимость).

В dataclasses пишите
@dataclass(slots=True) (Python 3.10+) вместо ручного __slots__.

Если нужен словарь атрибутов, добавьте '__dict__' в __slots__ — но тогда теряете экономию памяти.


🐍 Ghostly Python | #собес
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
😁252
🖼️ Библиотека: glom

glom — декларативная библиотека для извлечения и трансформации вложенных структур данных (dict/list/tuple). Позволяет описывать «что достать и как преобразовать» короткой спецификацией вместо ручных циклов и if.

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

🟢 Доступ к глубоко вложенным полям без try/except
🟢 Маппинг и агрегирование списков одной строкой
🟢 Значения по умолчанию и безопасные обходы отсутствующих ключей
🟢 Композиция спецификаций для сложных преобразований


⚙️ Пример использования:

from glom import glom, T

data = {
"user": {"name": "Alice", "age": 30, "emails": ["a@x.io", "b@y.io"]},
"orders": [{"id": 1, "total": 99.9}, {"id": 2, "total": 15.0}]
}

spec = {
"username": T["user"]["name"],
"primary_email": T["user"]["emails"][0],
"order_ids": (T["orders"], [T["id"]]),
"sum_total": (T["orders"], sum, [T["total"]]), # суммируем totals
}

print(glom(data, spec))
# ➔ {'username': 'Alice', 'primary_email': 'a@x.io', 'order_ids': [1, 2], 'sum_total': 114.9}

# Безопасный доступ с дефолтом:
print(glom(data, "user.phone", default="no phone")) # ➔ 'no phone'


✔️ Установка:

pip install glom


➡️ Ссылка на документацию

🐍 Ghostly Python | #библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
👍51
👩‍💻 Контейнерная стеганография: Прячем гигабайты в DOCX, PDF и еще десятке форматов

Я расширил ChameleonLab: от картинок к документам. Разбираю стеганографию в DOCX/PDF, риски, методики и защиту; покажу демо и грабли. Да, ваши отчёты тоже могут шептать.

➡️ Ссылка на статью

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
➡️ Python Tutor — визуализатор выполнения Python-кода в браузере

Python Tutor позволяет пошагово видеть, как исполняется ваш код: значения переменных, стек вызовов, переходы по строкам. Полезен для обучения, отладки рекурсий, понимания областей видимости и работы списков/словарей.

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


⛓️ Ссылка на ресурс

🐍 Ghostly Python | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Please open Telegram to view this post
VIEW IN TELEGRAM
😁147❤‍🔥2🙈2🤨1
📱 Фишка: functools.cached_property — ленивое свойство с кэшированием

cached_property превращает метод в свойство, которое вычисляется один раз при первом доступе и кэшируется в экземпляре. Полезно для дорогих вычислений и ленивой инициализации

from functools import cached_property
import time

class Report:
def init(self, user_id):
self.user_id = user_id

@cached_property
def stats(self):
print("Вычисляю...") # выполнится только при первом доступе
time.sleep(1)
return {"orders": 42, "spent": 199.99}


r = Report(123)
print(r.stats) # первый доступ — расчёт и кэширование
print(r.stats) # последующие — мгновенно из кэша
del r.dict["stats"] # инвалидация кэша
print(r.stats) # пересчёт после инвалидации


📌 Как это работает?

🟢 @cached_property сохраняет результат в instance.__dict__ под именем свойства.
🟢 Для обновления данных удалите кэш: del obj.__dict__["attr"] — значение пересчитается при следующем доступе.
🟢 Идеально для «ленивых» параметров: конфигов, аггрегатов из БД/API, тяжёлых вычислений

🐍 Ghostly Python | #фишки
Please open Telegram to view this post
VIEW IN TELEGRAM
5
👩‍💻 Напердолил целую игру

Покажу, как я собрал TANKOLINI NAPIERDOLKI: монохром, канвас и пиксели, тетрис-вайб и редактор карт; мультиплеер на Python, карты в PostgreSQL, комнаты в Redis. Мемы прилагаются.

➡️ Ссылка на статью

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
👌1
👩‍💻 Работа с конфигами TOML в Python с tomllib (+ запись через tomli-w)

TOML — удобный формат конфигураций. В Python 3.11+ есть встроенный tomllib для чтения; для записи используем лёгкий tomli-w.

⚙️ Пример: чтение → правка → сохранение

# pip install tomli-w
import tomllib # Python 3.11+
import tomli_w # запись TOML
from pathlib import Path

cfg = Path("config.toml")

# Создадим дефолтный конфиг, если его нет
cfg.write_text("[app]\nname='Ghostly'\ndebug=true\n\n[db]\nhost='localhost'\nport=5432\n",
encoding="utf-8") if not cfg.exists() else None

# Чтение (важно: бинарный режим для tomllib)
with cfg.open("rb") as f:
conf = tomllib.load(f)

# Изменим настройки
conf["app"]["debug"] = False
conf["db"]["host"] = "db.prod.local"
conf["db"]["port"] = 6432

# Запись обратно в TOML
cfg.write_text(tomli_w.dumps(conf), encoding="utf-8")


💬 Как это работает:

🟢 tomllib.load(f) — чтение TOML (3.11+); для ≤3.10 используйте tomli.
🟢 tomli_w.dumps(dict) — сериализация словаря в TOML.
🟢 Открывайте файл для tomllib в бинарном режиме: open("rb").
🟢 Разделяйте общие настройки и секреты (переменные окружения/.env).

🐍 Ghostly Python | #гайды
Please open Telegram to view this post
VIEW IN TELEGRAM
7🙏1
Please open Telegram to view this post
VIEW IN TELEGRAM
28😭18😁5
Вопрос с собеса

В чём разница между __getattr__ и __getattribute__ в Python и почему легко поймать бесконечную рекурсию?

Пример🔽
class Demo:
def __getattribute__(self, name):
if name == "x":
return 42
# ВАЖНО: делегировать наверх, иначе рекурсия
return super().__getattribute__(name)

def __getattr__(self, name):
# Вызывается ТОЛЬКО если обычный поиск атрибута провалился
return f"<missing:{name}>"

d = Demo()
print(d.x) # ➔ 42
print(d.y) # ➔ <missing:y>

class Bad:
def __getattribute__(self, name):
# Плохо: вызывает себя же через getattr → бесконечная рекурсия
return getattr(self, name)

# Bad().anything # ➔ RecursionError


Ответ🔽
__getattribute__(self, name) вызывается всегда при доступе к атрибуту экземпляра. Если внутри него вы обращаетесь к атрибутам через self.…/getattr(self, …), вы снова попадаете в __getattribute__ → RecursionError. Правильно — звать super().__getattribute__(name) или напрямую object.__getattribute__(self, name).

__getattr__(self, name) вызывается только если атрибут не найден обычным путём (включая __getattribute__). Удобен для ленивых/виртуальных атрибутов и значений по умолчанию.

🟢 Запомнить:

Внутри __getattribute__ используйте object.__getattribute__(self, name)/super() для безопасного доступа.

Чтобы передать управление __getattr__, поднимайте AttributeError из __getattribute__.

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

Для динамики часто достаточно __getattr__; __getattribute__ — инструмент «тяжёлого класса».


🐍 Ghostly Python | #собес
Please open Telegram to view this post
VIEW IN TELEGRAM
7
👩‍💻 Что если представить habr в виде obsidian-графа?

А что если спарсить часть статей с хабра и представить их в виде obsidian графа, будет ли это выглядеть, как красивая база знаний?

➡️ Ссылка на статью

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
😨4👍2🤯1
🖼️ Библиотека: Hypothesis

Hypothesis — библиотека для property-based тестирования: она сама генерирует входные данные, ищет контрпримеры и минимизирует (shrink) их до простого случая бага.

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

🟢 Автогенерация данных по стратегиям (st.integers(), st.text(), st.lists(...))
🟢 Поиск граничных случаев и минимизация падающих примеров
🟢 Интеграция с pytest/unittest без лишнего кода
🟢 Сохранение/повторение найденных контрпримеров


⚙️ Пример использования:

from hypothesis import given, strategies as st

# Свойство: двойной реверс списка возвращает исходное значение
@given(st.lists(st.integers()))
def test_reverse_twice(xs):
assert list(reversed(list(reversed(xs)))) == xs


✔️ Установка:

pip install hypothesis


➡️ Ссылка на документацию

🐍 Ghostly Python | #библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
5
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣231🤯1💯1
➡️ SuperFastPython — практические материалы по конкурентности и параллелизму в Python

Ресурс подробно разбирает threading, multiprocessing, asyncio, очереди, пулы процессов/потоков и шаблоны проектирования для высоконагруженных задач — с чёткими примерами и разбором подводных камней.

Примечательно, что статьи сопровождаются измерениями производительности и готовыми «рецептами» (тайм-ауты, отмена задач, ограничения параллелизма, ретраи), что помогает сразу применять приёмы в продакшене.


⛓️ Ссылка на ресурс

🐍 Ghostly Python | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
5
👩‍💻 Расширяем базовый функционал n8n: от RAG до кастомного агента с MCP

Я поднимаю n8n локально, учу его кастомным API и MCP-тулам: собираю AI-агента, не бросая no-code. Чуть кода — тонна гибкости. Скрины, грабли, профит.

➡️ Ссылка на статью

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
3
📱 Фишка: collections.ChainMap — объединение словарей с приоритетами

ChainMap позволяет работать с несколькими словарями как с одним: поиск ключей идёт слева направо, изменения пишутся в самый «верхний» словарь. Удобно для конфигов: CLI > ENV > defaults

from collections import ChainMap

defaults = {"host": "localhost", "port": 5432, "debug": False}
env = {"port": 6432}
cli = {"debug": True}

cfg = ChainMap(cli, env, defaults)

print(cfg["host"]) # ➔ localhost (из defaults)
print(cfg["port"]) # ➔ 6432 (из env)
print(cfg["debug"]) # ➔ True (из cli)

# Изменения пишутся в первый (cli)
cfg["port"] = 7000
print(cli) # ➔ {'debug': True, 'port': 7000}
print(env) # ➔ {'port': 6432} (не изменился)

# Временный «верхний» слой (например, сессия)
session = {"debug": False}
stacked = cfg.new_child(session)
print(stacked["debug"]) # ➔ False (приоритет session)


📌 Как это работает?

🟢 Поиск ключей: слева направо, без копирования словарей.
🟢 Запись всегда в первый мап (верхний слой).
🟢 new_child(mapping=None) добавляет слой, maps/parents — для управления стеком

🐍 Ghostly Python | #фишки
Please open Telegram to view this post
VIEW IN TELEGRAM
👍83