Formato Black / Ruff
Los formateadores automáticos eliminan los debates de estilo al imponer una salida determinista. Ruff format (compatible con Black) es la opción recomendada por defecto; Black sigue siendo ampliamente utilizado en proyectos existentes.
Receta
# Ruff format (recomendado)
uv run ruff format .
# Black (proyectos heredados)
uv run black .Cuándo usar esto:
- Para poner fin a debates de formato en la revisión de código
- Para imponer un estilo consistente en un equipo
- Ganchos de pre-commit que formatean automáticamente antes de confirmar
Ejemplo de trabajo
# Antes del formateo
def calculate_total(items, tax_rate=0.1, discount=0):
subtotal=sum(i.price*i.qty for i in items)
return subtotal*(1+tax_rate)-discount
# Después: uv run ruff format file.py
def calculate_total(items, tax_rate=0.1, discount=0):
subtotal = sum(i.price * i.qty for i in items)
return subtotal * (1 + tax_rate) - discount[tool.ruff.format]
line-length = 88
quote-style = "double"
indent-style = "space"uv run ruff format --check . # CI: falla si no está formateado
uv run ruff format . # corrige localmenteLo que esto demuestra:
- El formateador normaliza el espaciado, las comillas y los saltos de línea
- La salida es determinista: la misma entrada siempre produce la misma salida
- Modo
--checkpara CI sin modificar archivos - La configuración en
pyproject.tomlse aplica a todo el proyecto
Profundización
Cómo funciona
- El formateador analiza Python en un AST (Árbol de Sintaxis Abstracta) y luego lo vuelve a emitir con reglas consistentes
- La longitud de línea (por defecto 88) guía las decisiones de ajuste de línea
- La normalización de cadenas (comillas dobles por defecto) es configurable
- Ruff format tiene como objetivo una compatibilidad con Black superior al 99 %
Black vs Ruff Format
| Aspecto | Black | Ruff Format |
|---|---|---|
| Velocidad | Moderada | Muy rápida |
| Configuración | [tool.black] | [tool.ruff.format] |
| Compatibilidad | Implementación de referencia | Compatible con Black |
| Integración | Herramienta separada | Mismo binario que el linter |
Trampas comunes
- Formatear código generado - diffs ruidosos. Solución: excluir
migrations/,generated/en la configuración. - Ejecutar el formateador sin verificación de CI - se acumula deriva. Solución:
ruff format --checken CI. - Anulaciones manuales de estilo - los bloques
# fmt: off/ondeben ser raros. Solución: usar con moderación para casos legítimos (cadenas SQL largas). - Diferente longitud de línea en el linter y el formateador - E501 se activa en código formateado. Solución: ignorar E501 en el lint de ruff; establecer una única
line-length. - Mezclar Black y ruff format - diferencias sutiles en la salida causan cambios constantes. Solución: elegir uno; eliminar el otro.
Alternativas
| Alternativa | Usar cuándo | No usar cuándo |
|---|---|---|
| autopep8 | Cambios mínimos en el estilo existente | Quieres determinismo completo |
| yapf | Preferencia por el estilo de Google | El equipo quiere compatibilidad con Black |
| Formateo manual | Scripts individuales | Cualquier proyecto de equipo |
Preguntas frecuentes
¿Debería usar Black o ruff format?
Proyectos nuevos: ruff format (más rápido, integrado). Proyectos existentes con Black: migrar cuando sea conveniente.
¿Qué longitud de línea debo usar?
88 (predeterminado de Black) es el estándar de la comunidad Python. Coincide con la configuración de tu linter.
¿Cómo omito el formateo de un bloque?
# fmt: off antes y # fmt: on después del bloque.
¿El formateador cambia las comillas de las cadenas?
Sí, por defecto a comillas dobles. Configura con quote-style = "single".
¿Puedo formatear notebooks de Jupyter?
ruff format notebook.ipynb (ruff 0.6+). Black también soporta notebooks.
¿El formateo romperá mi código?
No. Los formateadores solo cambian el espacio en blanco y el estilo de las comillas, nunca la semántica.
¿Cómo formateo al guardar en VS Code?
Establece "editor.defaultFormatter": "charliermarsh.ruff" y "editor.formatOnSave": true.
¿Se deben formatear las migraciones generadas?
Exclúyelas. Añade exclude = ["migrations"] para evitar diffs ruidosos.
¿Cómo verifico un solo archivo?
ruff format path/to/file.py o black path/to/file.py.
¿El formateo afecta el orden de las importaciones?
No. La ordenación de importaciones es ruff check --fix (reglas de isort), no el formateador.
Relacionado
- Configuración de Ruff - configuración completa de ruff
- isort y Organización de Importaciones - ordenación de importaciones
- Ganchos de pre-commit - formatear al confirmar
- Mejores Prácticas de Linting y Formateo - política de equipo
Versiones de la pila: Esta página fue escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.