Escribir Python que funciona es fácil. Escribir Python que otra persona —o tú dentro de seis meses— pueda leer, modificar y en el que pueda confiar es otra historia. Y casi nada de eso depende de trucos del lenguaje: depende de hábitos sencillos repetidos con disciplina.

Nombres que dicen lo que hacen
Un buen nombre es la única documentación que nunca queda desactualizada. d no dice nada; dias_de_retraso sí. process() es vago; enviar_cobro() cuenta la historia. Cuando necesitas un comentario solo para explicar qué guarda una variable, normalmente el problema está en el nombre.
Reserva los nombres cortos para los ámbitos pequeños: la i de un for de tres líneas está perfecta. Fuera de eso, prefiere la claridad al ahorro de teclas. Nadie se ha quejado nunca de que un nombre fuera demasiado legible.
Funciones que hacen una sola cosa

Una función que valida el formulario, guarda en la base de datos y además envía el correo de confirmación en realidad son tres funciones fingiendo ser una. El día que quieras probar solo la validación, tendrás que levantar también la base de datos y el servidor de correo. Sepáralas.
La prueba práctica está en el nombre: si para describir la función usas un «y» («valida y guarda y notifica»), probablemente hace demasiadas cosas. Las funciones pequeñas y enfocadas son más fáciles de leer, probar y reutilizar; además, el código de nivel superior, que simplemente llama a una tras otra, se convierte casi en un resumen de lo que ocurre.
No abstraigas demasiado pronto
Existe una tentación casi irresistible de crear, al ver dos fragmentos parecidos, una función genial que resuelva ambos problemas. Espera. La duplicación es barata y visible; la abstracción equivocada es cara y se queda pegada. Una función con siete parámetros y tres flags booleanos casi siempre nació de una generalización apresurada.
La regla práctica es esperar a que el patrón se repita por tercera vez antes de extraerlo. Para entonces ya habrás visto suficiente variación como para saber qué es realmente común. Abstrae lo que haya demostrado ser estable, no lo que imaginas que quizá cambie algún día.
Aísla el entorno y fija las dependencias

«En mi máquina funciona» casi siempre es una historia sobre dependencias. Un entorno virtual por proyecto (python -m venv .venv) evita que la biblioteca de un proyecto contamine a otro y mantiene limpio tu Python global.
Más importante aún: fija las versiones. Un requirements.txt con versiones exactas, o una herramienta con un archivo de lock, garantiza que quien clone el repositorio mañana instale exactamente lo que probaste hoy. Una dependencia sin versión fijada es una actualización silenciosa esperando romper el build en el peor momento.
Type hints donde realmente ayudan
Los type hints no hacen que Python sea más rápido, pero sí hacen que tu editor y tus compañeros sean mucho más inteligentes. Anota allí donde el beneficio sea mayor: en las fronteras públicas —las firmas de las funciones y los valores de retorno—. def calcular_total(itens: list[Item]) -> Decimal: ya dice más que un párrafo de docstring.
Ejecuta un comprobador como mypy en el CI para que esas anotaciones se verifiquen de verdad y no se conviertan en adornos. Pero no caigas en el exceso de tipar cada variable local obvia: un hint es una herramienta de comunicación, no un impuesto. Cuando no aclara, estorba.
Errores explícitos y pruebas como hábito
Un except Exception: pass es un lugar donde los bugs se instalarán gratis. Captura la excepción específica que sabes manejar y deja que el resto se manifieste: un error evidente en el lugar correcto es infinitamente mejor que un sistema que falla en silencio. Prefiere fallar pronto antes que ocultar el problema.
Y las pruebas no son una fase posterior al código; forman parte de escribirlo. No hace falta apuntar al 100 % de cobertura el primer día: empieza por los casos límite y por los caminos que, si fallan, más duelen. Un puñado de buenas pruebas compra algo que ninguna cantidad de cuidado manual puede ofrecer: valor para refactorizar.
El código limpio no es vanidad ni perfeccionismo. Es lo que permite cambiar rápido y sin miedo cuando cambia el requisito —y siempre cambia—. Empieza por un hábito, aplícalo en el próximo commit y deja que el resto llegue después.

