← Назад к вопросам

Какие инструменты отладки (pdb, logging) используешь?

1.3 Junior🔥 111 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие инструменты отладки используешь

Использую комплексный подход отладки в зависимости от типа задачи.

1. pdb (Python Debugger)

Встроенный интерактивный отладчик:

import pdb

def process_data(data):
    result = []
    for item in data:
        pdb.set_trace()  # Точка останова
        processed = item * 2
        result.append(processed)
    return result

# Команды в pdb:
# n - next (следующая строка)
# s - step (заход в функцию)
# c - continue (выполнить до след. breakpoint)
# l - list (показать код)
# p variable - вывести переменную
# pp variable - красивый вывод

Лучше: использовать breakpoint() (Python 3.7+):

def calculate(a, b):
    result = a + b
    breakpoint()  # Вводит в pdb
    return result

2. Logging (основной инструмент)

Структурированное логирование:

import logging
from datetime import datetime

# Конфигурация
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('app.log'),
        logging.StreamHandler()
    ]
)

logger = logging.getLogger(__name__)

# Использование
def extract_data(query):
    logger.info(f"Starting extraction with query: {query[:100]}")
    try:
        data = fetch_from_db(query)
        logger.info(f"Extracted {len(data)} rows")
        return data
    except Exception as e:
        logger.error(f"Extraction failed: {e}", exc_info=True)
        raise

# Уровни логирования
logger.debug("Detailed debug info")
logger.info("General information")
logger.warning("Warning: something unusual")
logger.error("Error: operation failed")
logger.critical("Critical: system failure")

3. Structured Logging (JSON)

import logging
import json
from datetime import datetime

class JSONFormatter(logging.Formatter):
    def format(self, record):
        log_data = {
            'timestamp': datetime.utcnow().isoformat(),
            'level': record.levelname,
            'logger': record.name,
            'message': record.getMessage(),
            'module': record.module,
            'function': record.funcName,
            'line': record.lineno
        }
        
        if record.exc_info:
            log_data['exception'] = self.formatException(record.exc_info)
        
        return json.dumps(log_data)

# Использование
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)

logger.info("Process started", extra={'user_id': 123, 'batch_size': 1000})

4. Контекстное логирование

import logging
from contextlib import contextmanager

@contextmanager
def log_context(logger, operation, **context):
    logger.info(f"Starting: {operation}", extra=context)
    try:
        yield
        logger.info(f"Completed: {operation}")
    except Exception as e:
        logger.error(f"Failed: {operation}", extra={**context, 'error': str(e)})
        raise

# Использование
with log_context(logger, 'data_pipeline', user_id=123, table='orders'):
    process_orders()

5. Timing и Performance Profiling

import time
import logging
from functools import wraps

def log_timing(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        logger.info(f"Starting {func.__name__}")
        
        try:
            result = func(*args, **kwargs)
            duration = time.time() - start
            logger.info(f"Completed {func.__name__} in {duration:.2f}s")
            return result
        except Exception as e:
            duration = time.time() - start
            logger.error(f"Failed {func.__name__} after {duration:.2f}s: {e}")
            raise
    
    return wrapper

@log_timing
def slow_operation():
    time.sleep(2)
    return "done"

6. Assertions для контроля качества

def process_orders(orders):
    assert isinstance(orders, list), "orders must be a list"
    assert len(orders) > 0, "orders cannot be empty"
    
    for order in orders:
        assert 'id' in order, "Order must have id"
        assert order['amount'] > 0, f"Amount must be positive: {order}"
    
    return sum(o['amount'] for o in orders)

7. Debug Print функции

import json
from pprint import pprint

def debug_df(df, name="DataFrame"):
    print(f"\n=== {name} ===")
    print(f"Shape: {df.shape}")
    print(f"Columns: {df.columns.tolist()}")
    print(f"Dtypes:\n{df.dtypes}")
    print(f"\nFirst rows:")
    print(df.head())
    print(f"\nMissing values:\n{df.isnull().sum()}")

def debug_query_result(data):
    if isinstance(data, list) and len(data) > 0:
        print(f"Records: {len(data)}")
        print("First record:")
        pprint(data[0])

8. Exception Tracking (Sentry)

import sentry_sdk

sentry_sdk.init(dsn="https://examplePublicKey@o0.ingest.sentry.io/0")

def process_batch():
    try:
        risky_operation()
    except Exception as e:
        sentry_sdk.capture_exception(e)
        raise

9. Unit Testing для отладки

import pytest

def test_process_data():
    input_data = [1, 2, 3]
    expected = [2, 4, 6]
    
    result = process_data(input_data)
    
    assert result == expected, f"Expected {expected}, got {result}"
    
    # Запуск с debug: pytest --pdb test_file.py

10. Remote Debugging (Production)

import remote_pdb

# В production коде
if DEBUG_MODE:
    remote_pdb.RemotePdb('127.0.0.1', 4444).set_trace()

# Подключение: telnet localhost 4444

Мой типичный workflow

  1. Во время разработки: logging + pytest
  2. При ошибке в dev: pdb/breakpoint()
  3. В production: structured JSON logging + Sentry
  4. Для performance: timing декораторы + профилирование
  5. В pipeline: assert statements + quality checks

Результат: 95% ошибок отловляются до production через логирование и тесты.

Какие инструменты отладки (pdb, logging) используешь? | PrepBro