Ghostly Python
9.04K 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
👍11😁3
📱 Фишка: functools.lru_cache — мемоизация в одну строку

lru_cache кэширует результаты функции по её аргументам, резко ускоряя повторные вызовы. Идеально для рекурсий, дорогостоящих вычислений и запросов, которые часто повторяются с одинаковыми параметрами.

from functools import lru_cache
from time import perf_counter

@lru_cache(maxsize=256) # LRU-кэш на 256 последних комбинаций аргументов
def fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n - 2)

t0 = perf_counter(); print(fib(35)); t1 = perf_counter() - t0
t0 = perf_counter(); print(fib(35)); t2 = perf_counter() - t0
print(f"Первый вызов: {t1:.4f} c, повторный: {t2:.6f} c") # второй практически мгновенный


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

🟢 @lru_cache(maxsize=N) запоминает результаты по хэшируемым аргументам и автоматически очищает старые записи (LRU).
🟢 maxsize=None — безлимитный кэш; func.cache_clear() — сброс; func.cache_info() — статистика хитов/промахов.
🟢 Работает только с хэшируемыми аргументами (числа, строки, кортежи и т.п.); для неизменяемых структур данных — идеально.

🐍 Ghostly Python | #фишки
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21
👩‍💻 Позиционный трейдинг + ML: от нуля до торговой стратегии за год

В статье рассказывается о создании стратегии для позиционной торговли. Показан опыт разработки инструмента для проверки торговых идей.

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


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

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🤔21
👩‍💻 Работа с файловой системой на Python с помощью pathlib

pathlib — современный и удобный способ работать с путями, файлами и директориями кроссплатформенно. Заменяет os.path и делает код короче и понятнее.

⚙️ Пример: создание папки, запись/чтение файла, поиск по маске, переименование и удаление

from pathlib import Path

# Базовая директория проекта
base = Path.cwd()

# Создаём папку data (если нет)
data_dir = base / "data"
data_dir.mkdir(parents=True, exist_ok=True)

# Путь к файлу
file = data_dir / "notes.txt"

# Запись текста в файл (перезапишет если существует)
file.write_text("Привет, pathlib!\n", encoding="utf-8")

# Дозапись строки
with file.open("a", encoding="utf-8") as f:
f.write("Ещё одна строка.\n")

# Чтение всего содержимого
content = file.read_text(encoding="utf-8")
print("Содержимое файла:\n", content)

# Перебор всех .txt в папке
for p in data_dir.glob("*.txt"):
print("Файл:", p.name, "| размер:", p.stat().st_size, "байт")

# Переименование файла
archived = file.with_name("notes-archived.txt")
file.rename(archived)

# Удаление файла (раскомментируйте при необходимости)
# archived.unlink()


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

🟢 Path — объектный путь; оператор / соединяет сегменты путей.
🟢 mkdir(parents=True, exist_ok=True) создаёт дерево директорий безопасно.
🟢 write_text() / read_text() — быстрые шорткаты для записи/чтения.
🟢 open("a") — дозапись без перезаписи.
🟢 glob("*.txt") и rglob("**/*.txt") — поиск по маске (включая рекурсивно).
🟢 with_name(), rename(), unlink() — удобные операции с файлами

🐍 Ghostly Python | #гайды
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Please open Telegram to view this post
VIEW IN TELEGRAM
😁24👍3😨2
Вопрос с собеса

Почему этот код печатает [2, 2, 2], а не [0, 1, 2]?

Пример🔽
# Неверно: late binding захватывает ИМЯ переменной i
funcs = [lambda: i for i in range(3)]
print([f() for f in funcs]) # ➔ [2, 2, 2]

# Верно: захватить ТЕКУЩЕЕ значение через аргумент по умолчанию
funcs = [lambda i=i: i for i in range(3)]
print([f() for f in funcs]) # ➔ [0, 1, 2]


Ответ🔽
Лямбды/замыкания в Python делают позднее связывание (late binding): они запоминают не значение i, а имя. Когда вызов происходит, цикл уже завершён, и i == 2 для всех функций. Передача i как аргумента по умолчанию фиксирует значение в момент создания функции.

🟢 Запомнить:

В замыканиях значения берите через lambda i=i: ... или functools.partial(...).

Та же ловушка есть в comprehensions и циклах с замыканиями.

Проверяйте такие конструкции тестом — легко промахнуться.


🐍 Ghostly Python | #собес
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7
👩‍💻 PEP 723 + uv: однофайловые скрипты с зависимостями

Покажу PEP 723+uv: зависимости в комментариях, раннер сам ставит и запускает. Примеры, плюсы и грабли, отдельно — про риски безопасности. Без README-плясок.

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

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

Tenacity — гибкая библиотека для ретраев (повторных попыток) с поддержкой экспоненциального бэкоффа, фильтрации по исключениям/результатам и асинхронных функций. Полезна для сетевых запросов, нестабильных API и flaky-тестов.

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

🟢 Декларативные ретраи через декоратор @retry
🟢 Стратегии ожидания: фиксированная, экспоненциальная, джиттер, лимиты
🟢 Условия повтора по типам исключений или значениям результата
🟢 Хуки before/after и поддержка async def


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

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import requests

@retry(
stop=stop_after_attempt(5), # максимум 5 попыток
wait=wait_exponential(multiplier=0.5, max=8), # экспоненциальный бэкофф
retry=retry_if_exception_type((
requests.exceptions.Timeout,
requests.exceptions.ConnectionError,
)),
reraise=True # пробросить последнее исключение
)
def fetch_json(url: str) -> dict:
resp = requests.get(url, timeout=2)
resp.raise_for_status()
return resp.json()

data = fetch_json("https://httpbin.org/json")
print(data["slideshow"]["title"])


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

pip install tenacity


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

🐍 Ghostly Python | #библиотеки
Please open Telegram to view this post
VIEW IN TELEGRAM
1
Please open Telegram to view this post
VIEW IN TELEGRAM
👏7😁1
➡️ The Hitchhiker’s Guide to Python — практическое руководство по экосистеме Python

Ресурс охватывает настройку окружений (venv/pyenv), управление зависимостями, упаковку и публикацию пакетов, тестирование, логирование, стиль кода и структуру проектов. Полезен как чеклист “best practices” для ежедневной разработки.

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


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

🐍 Ghostly Python | #ресурсы
Please open Telegram to view this post
VIEW IN TELEGRAM
1
👩‍💻 Тихий герой воскресного утра: как bash-скрипт спас нас от OOM Killer

Опишу, как в воскресенье API-гейтвей устроил бой с памятью, а простой скрипт вытащил прод: что случилось, как сработало, код, графики, постмортем и чек-лист.

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

🐍 Ghostly Python | #статьи
Please open Telegram to view this post
VIEW IN TELEGRAM
2
📱 Фишка: functools.singledispatch — перегрузка функций по типу аргумента

singledispatch позволяет объявить одну «общую» функцию и регистрировать для неё разные реализации в зависимости от типа первого аргумента. Удобно для сериализации, валидации и преобразований без длинных if isinstance(...).

from functools import singledispatch

@singledispatch
def serialize(obj):
return str(obj) # поведение по умолчанию

@serialize.register
def _(obj: int):
return f"int:{obj}"

@serialize.register
def _(obj: list):
return f"list[{len(obj)}]"

print(serialize(10)) # ➔ int:10
print(serialize([1, 2, 3]))# ➔ list[3]
print(serialize(3.14)) # ➔ 3.14 (попадает в базовую реализацию)


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

🟢 @singledispatch выбирает реализацию по типу первого аргумента с учётом MRO (находит ближайший подходящий тип).
🟢 .register(Type) добавляет реализацию для конкретного типа (и её унаследуют подклассы).
🟢 Есть вариант для методов — functools.singledispatchmethod (класс-ориентированная перегрузка).

🐍 Ghostly Python | #фишки
Please open Telegram to view this post
VIEW IN TELEGRAM
2
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