10 промтов для Python-разработчика: как закрывать задачи быстрее, пока коллеги гуглят исключения
Каждый Python-разработчик знает это чувство: ты уже третий раз гуглишь TypeError: 'NoneType' object is not subscriptable, листаешь Stack Overflow 2014 года и понимаешь, что ответ устарел ещё до выхода Python 3.10. Пока ты читаешь чужой вопрос, LLM уже могла бы написать тебе рабочий код — если правильно сформулировать запрос.
Проблема в том, что большинство промтов в интернете выглядят как «напиши функцию для сортировки». Это бесполезно. Хороший промт для Python — это не «сделай мне код», а «вот контекст, вот ограничения, вот ожидаемое поведение, покажи решение и объясни edge cases». Разница — как между pip install и pip install --no-cache-dir -r requirements.txt.
Ниже — 10 промтов, которые я реально использую в работе: от генерации типизированных функций до отладки падающих pytest-тестов и деплоя FastAPI. Каждый с примером, пояснением и указанием, для какой задачи подходит. Всё проверено на Python 3.12+ и актуальных версиях библиотек на сентябрь 2026.
1. Генерация типизированной функции с docstring по стандарту Google
Когда нужно быстро написать утилиту, но лень вспоминать формат docstring и аннотации типов. Промт заставляет модель сразу выдать production-ready код, а не псевдокод.
Промт:
You are a senior Python developer. Write a function with full type hints (PEP 484/604) and a Google-style docstring.
Signature requirements:
- Function name: {name}
- Inputs: {describe inputs}
- Output: {describe output}
- Must raise {ExceptionType} when {condition}
Return ONLY the function code, no explanations. Use Python 3.12 syntax (X | None instead of Optional[X]).
Пример использования: нужна функция, которая парсит строку с датой и возвращает datetime, кидая ValueError на пустой строке.
from datetime import datetime
def parse_date(value: str, fmt: str = "%Y-%m-%d") -> datetime:
"""Parse a date string into a datetime object.
Args:
value: Date string to parse.
fmt: strptime format string, defaults to ISO-like "%Y-%m-%d".
Returns:
Parsed datetime object.
Raises:
ValueError: If value is empty or does not match fmt.
"""
if not value:
raise ValueError("value must be a non-empty string")
return datetime.strptime(value, fmt)
Подходит для junior-задач, но с явным указанием типов выдаёт код, который проходит mypy --strict без правок.
2. Рефакторинг «божественного класса» в dataclass
Классика легаси: класс на 400 строк с кучей полей и методов. Промт помогает разбить его на dataclass + отдельные функции, сохранив поведение.
Промт:
Refactor the following Python class into a @dataclass (frozen if no mutation needed) plus pure functions.
Preserve the public API: same method names and signatures.
Do not change behavior. Point out any hidden state you found.
Class code:
{paste code}
Пример: класс User с полями name, email, created_at и методами is_active(), display_name(). На выходе — @dataclass(frozen=True) class User и функция display_name(user: User) -> str. Модель отдельно сообщит, что is_active зависел от глобального CURRENT_DATE, — это и есть «hidden state», который ломает тесты.
3. Pandas: векторизация вместо apply
df.apply(..., axis=1) на 10 млн строк работает часами. Промт заставляет переписать логику на векторные операции pandas.
Промт:
Rewrite this pandas code to avoid .apply(axis=1) and python-level loops.
Use vectorized operations (np.where, .map, .str accessor, boolean masks).
Keep the same output DataFrame columns and dtypes.
Benchmark hint: assume the DataFrame has 10M rows.
Code:
{paste code}
Пример: было
df["category"] = df.apply(
lambda r: "big" if r["amount"] > 1000 and r["country"] == "US" else "small",
axis=1,
)
стало
import numpy as np
df["category"] = np.where(
(df["amount"] > 1000) & (df["country"] == "US"), "big", "small"
)
Для справки: официальная документация pandas в разделе Enhancing performance прямо рекомендует избегать apply там, где есть векторизация.
4. SQLAlchemy 2.0: async-запрос с relationship
Если вы мигрируете с SQLAlchemy 1.4 на 2.0, синтаксис select() с AsyncSession легко перепутать. Промт генерирует корректный async-запрос с selectinload.
Промт:
Write an async SQLAlchemy 2.0 query using AsyncSession.
Models: User (id, name), Order (id, user_id, total), relationship User.orders.
Task: fetch users with their orders where order.total > {threshold}, avoid N+1.
Use selectinload. Show the model definitions and the query.
Пример результата:
from sqlalchemy import select
from sqlalchemy.orm import selectinload
stmt = (
select(User)
.options(selectinload(User.orders))
.where(User.orders.any(Order.total > threshold))
)
result = await session.execute(stmt)
users = result.scalars().unique().all()
Обратите внимание на .unique() — без него selectinload с коллекциями кидает InvalidRequestError. Документация SQLAlchemy 2.0 описывает это в разделе ORM Querying Guide.
5. pytest: параметризация и фикстуры вместо копипасты
Когда тесты копипастятся под каждый кейс. Промт превращает их в @pytest.mark.parametrize с фикстурами.
Промт:
Refactor these pytest tests:
- Replace repeated test bodies with @pytest.mark.parametrize
- Extract shared setup into fixtures
- Add edge cases I might have missed (empty input, None, boundary values)
- Use pytest.raises for error paths
Tests:
{paste tests}
Пример: вместо трёх тестов test_parse_iso, test_parse_slash, test_parse_dot получаем:
import pytest
@pytest.mark.parametrize("value,expected", [
("2026-09-26", datetime(2026, 9, 26)),
("2026/09/26", datetime(2026, 9, 26)),
("26.09.2026", datetime(2026, 9, 26)),
])
def test_parse_date(value, expected):
assert parse_date(value, fmt=guess_fmt(value)) == expected
@pytest.mark.parametrize("bad", ["", None, "not-a-date"])
def test_parse_date_raises(bad):
with pytest.raises(ValueError):
parse_date(bad)
Плюс модель сама подсветит, что None без аннотации str | None вызовет TypeError до ValueError, — это ровно тот edge case, который забывают.
6. Оптимизация медленного кода: профилирование и замена алгоритма
Промт не просто «ускорь», а заставляет сначала оценить сложность.
Промт:
Analyze this Python function for performance.
1. Estimate time complexity (Big-O) of current implementation.
2. Identify the bottleneck.
3. Propose a faster version with better complexity.
4. Show how to verify with cProfile / timeit.
Code:
{paste code}
Пример: функция поиска дубликатов через вложенные циклы O(n²) переписывается на set за O(n):
def find_duplicates(items: list[int]) -> list[int]:
seen: set[int] = set()
dupes: set[int] = set()
for x in items:
if x in seen:
dupes.add(x)
seen.add(x)
return list(dupes)
Проверка через стандартный модуль timeit (python -m timeit -s "...") показывает разницу на порядки уже на массиве в 100k элементов.
7. Обработка исключений и логирование без «except: pass»
Промт, который вычищает антипаттерн except Exception: pass и добавляет структурное логирование.
Промт:
Rewrite exception handling in this code:
- Catch only specific exceptions (no bare except)
- Add structured logging via the logging module (logger = logging.getLogger(__name__))
- Include context (function name, args) in log records
- Re-raise with 'raise ... from e' to preserve traceback
Code:
{paste code}
Пример: было
try:
data = json.loads(raw)
except:
pass
стало
import logging
logger = logging.getLogger(__name__)
try:
data = json.loads(raw)
except json.JSONDecodeError as e:
logger.warning("invalid json payload", extra={"raw_len": len(raw)})
raise ValueError("payload is not valid JSON") from e
Это соответствует рекомендациям из PEP 3134 о chained exceptions и официальному Logging HOWTO.
8. Парсинг данных: httpx + selectolax вместо requests + BeautifulSoup
Промт для быстрого парсера, который не падает на динамических страницах и корректно ставит User-Agent.
Промт:
Write a Python parser using httpx (async) and selectolax.
Target: extract {fields} from {url}.
Requirements:
- Set a realistic User-Agent and timeout
- Handle HTTP 429 with exponential backoff (tenacity)
- Parse with CSS selectors, return list[dict]
- Do not use Selenium unless JS rendering is required
Пример:
import asyncio, httpx
from selectolax.parser import HTMLParser
async def fetch_titles(url: str) -> list[dict]:
headers = {"User-Agent": "Mozilla/5.0 (compatible; MyBot/1.0)"}
async with httpx.AsyncClient(timeout=10.0, headers=headers) as client:
r = await client.get(url)
r.raise_for_status()
tree = HTMLParser(r.text)
return [{"title": n.text(strip=True)} for n in tree.css("h2.article-title")]
asyncio.run(fetch_titles("https://example.com/blog"))
Важно: перед парсингом проверяйте robots.txt и условия сайта — это не техническое, но обязательное требование.
9. FastAPI: эндпоинт с Pydantic v2 и обработкой ошибок
Промт для генерации эндпоинта по актуальному синтаксису Pydantic v2 (model_config, field_validator).
Промт:
Write a FastAPI endpoint using Pydantic v2.
- Request model: {fields} with validation (e.g. email format, positive int)
- Response model with computed field
- Custom exception handler returning RFC 7807 problem+json
- Async DB call stub
Do not use deprecated Pydantic v1 syntax (no @validator, no Config class).
Пример:
from pydantic import BaseModel, EmailStr, Field, computed_field
class UserIn(BaseModel):
email: EmailStr
age: int = Field(gt=0, lt=120)
@computed_field
@property
def domain(self) -> str:
return self.email.split("@")[1]
RFC 7807 (application/problem+json) — реальный стандарт, описан в IETF RFC 7807. Он задаёт поля type, title, status, detail, instance для машиночитаемых ошибок API.
10. Деплой FastAPI: Dockerfile + healthcheck без раздутого образа
Финальный промт — упаковка сервиса в контейнер с multi-stage build и non-root пользователем.
Промт:
Write a production Dockerfile for a FastAPI app.
- Multi-stage: builder installs deps with pip --no-cache-dir into a venv, runtime copies venv
- Base image: python:3.12-slim
- Create non-root user, switch to it
- Add HEALTHCHECK hitting /health
- CMD: uvicorn with --workers {n}
Also show the matching docker-compose.yml with postgres and healthcheck.
Пример (фрагмент):
FROM python:3.12-slim AS builder
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.12-slim
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN useradd -m appuser
USER appuser
COPY . /app
WORKDIR /app
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Бонус — 11-й промт для отладки трейсбеков. Когда ничего не помогает, вставляете полный трейсбек и промт: Here is a Python traceback. Explain the root cause in 3 sentences, then give a minimal reproducible fix. Do not suggest reinstalling packages unless the traceback shows an import error. — это экономит десятки минут на гуглении.
Что важно помнить
Промты работают, когда вы даёте контекст: версию Python, версии библиотек, ожидаемое поведение и ограничения. Модель не знает, что у вас SQLAlchemy 2.0, а не 1.4, если вы не напишете это явно. И всегда проверяйте сгенерированный код: LLM уверенно выдаёт pd.append (удалён в pandas 2.0) или @validator из Pydantic v1, потому что в обучающих данных их было много. Комбинация «хороший промт + запуск тестов + чтение официальной документации» закрывает задачу быстрее, чем час поиска по Stack Overflow.
Начните с двух-трёх промтов из списка на ближайшей задаче — например, рефакторинга тестов и векторизации pandas. Дальше вы быстро соберёте свой набор под конкретный стек, и гуглить исключения придётся заметно реже.
Comments