Python 2 y Python 3 comparten el mismo origen, pero no son versiones intercambiables. Python 3 fue diseñado para corregir decisiones históricas, simplificar el lenguaje y preparar una base más coherente para el futuro. Hoy, Python 2 está fuera de soporte y no debe utilizarse para nuevos proyectos. Aun así, comprender sus diferencias sigue siendo útil cuando se mantiene software antiguo o se migra una aplicación heredada.
Estado de soporte
Python 2 llegó al final de su vida oficial el 1 de enero de 2020. Desde entonces no recibe correcciones normales de errores ni actualizaciones de seguridad por parte del proyecto Python. La página oficial Sunsetting Python 2 explica el cierre del ciclo. Para desarrollo actual, la elección correcta es una versión mantenida de Python 3.
print: sentencia frente a función
En Python 2, print era una sentencia:
print "Hola"En Python 3 es una función:
print("Hola")El cambio permite usar parámetros, redirección y composición de forma uniforme. También facilita comprender que print muestra datos, mientras que return devuelve resultados desde una función.
División de enteros
En Python 2, dividir dos enteros con / podía producir una división entera:
# Python 2
5 / 2 # 2En Python 3, / produce división real:
5 / 2 # 2.5
5 // 2 # 2El operador // expresa de forma explícita la división entera. La guía de operadores en Python profundiza en estas diferencias.
Unicode y cadenas
Python 3 utiliza Unicode como tipo de texto predeterminado. Los bytes son un tipo separado. Esta distinción reduce muchos problemas internacionales y obliga a decidir cuándo se codifica o decodifica.
texto = "España"
datos = texto.encode("utf-8")
recuperado = datos.decode("utf-8")En Python 2, str representaba bytes y unicode representaba texto Unicode. Mezclar ambos tipos generaba errores difíciles de reproducir.
range y xrange
Python 2 incluía range, que creaba una lista, y xrange, que generaba valores bajo demanda. Python 3 conserva solo range, pero con comportamiento eficiente similar a xrange.
for numero in range(1_000_000):
procesar(numero)Este diseño evita crear una lista enorme sin necesidad. Para otros patrones de evaluación perezosa, revisa itertools en Python.
Entrada del usuario
En Python 2, raw_input devolvía texto, mientras que input evaluaba la entrada como código, lo que podía ser peligroso. Python 3 utiliza input para devolver una cadena:
edad = int(input("Edad: "))La conversión es explícita y puede validarse.
Excepciones
La sintaxis moderna usa as:
try:
abrir_archivo()
except OSError as error:
print(error)Python 2 permitía formas antiguas que ya no son válidas. Durante una migración, las excepciones deben revisarse junto con sus clases y mensajes.
Iteradores en diccionarios
Métodos como dict.keys(), values() e items() devuelven vistas en Python 3, no listas completas. Esto reduce memoria y refleja cambios en tiempo real:
usuario = {"nombre": "Ana", "edad": 30}
for clave, valor in usuario.items():
print(clave, valor)En Python 2 existían variantes como iteritems(). Al migrar, conviene eliminar esas llamadas.
Comparaciones más estrictas
Python 2 permitía ordenar objetos de tipos incompatibles en algunos casos. Python 3 suele lanzar TypeError:
# Python 3
1 < "2" # TypeErrorEsta restricción evita órdenes arbitrarios y obliga a convertir o normalizar datos.
Clases de nuevo estilo
En Python 2, una clase debía heredar de object para obtener el modelo moderno:
class Usuario(object):
passEn Python 3 todas las clases utilizan el modelo nuevo:
class Usuario:
passEsto simplifica herencia, propiedades y resolución de métodos.
Type hints
Python 3 desarrolló un ecosistema moderno de anotaciones:
def sumar(a: int, b: int) -> int:
return a + bLos type hints mejoran editores y análisis estático. No forman parte práctica del desarrollo con Python 2.
f-strings
Las f-strings, disponibles en Python 3 moderno, permiten formato claro:
nombre = "Marta"
mensaje = f"Hola, {nombre}"Python 2 dependía de % o str.format. Al migrar, no es obligatorio convertir todo, pero las f-strings suelen mejorar legibilidad.
Bibliotecas y compatibilidad
La mayoría de bibliotecas activas abandonó Python 2. Intentar mantener dependencias antiguas aumenta riesgos de seguridad, incompatibilidades con sistemas operativos y dificultades de instalación. La gestión moderna de dependencias con herramientas como Poetry está orientada a Python 3.
Cómo migrar un proyecto
Primero crea pruebas que documenten el comportamiento actual. La guía de pruebas unitarias en Python ayuda a construir esa red de seguridad. Después identifica dependencias, elige una versión objetivo de Python 3 y ejecuta herramientas de análisis.
La guía oficial para portar código a Python 3 recomienda modernizar gradualmente, actualizar dependencias y mantener pruebas continuas.
Herramientas de migración
2to3 fue útil históricamente, pero no sustituye una revisión manual y ha perdido relevancia en versiones recientes. Herramientas como pyupgrade, linters y analizadores pueden ayudar. La migración debe revisar texto, bytes, división, iteradores, excepciones e interfaces de bibliotecas.
No cambiar todo al mismo tiempo
En aplicaciones grandes, divide la migración por módulos. Añade pruebas, actualiza sintaxis, ejecuta el sistema y corrige diferencias semánticas. También prepara un entorno reproducible y registra las versiones de dependencias.
Seguridad del código legado
Un servicio Python 2 expuesto a Internet representa un riesgo creciente. Si no puede migrarse inmediatamente, reduce su superficie: aísla la red, limita permisos, evita nuevas funciones y planifica una sustitución. El aislamiento es temporal, no una alternativa permanente a la migración.
Qué versión aprender
Quien comienza debe aprender Python 3. Las diferencias de Python 2 solo importan para leer código antiguo. Para consolidar la base moderna, consulta esta guía de Python desde cero.
Conclusión
Python 3 ofrece texto Unicode coherente, división explícita, iteradores eficientes, sintaxis moderna, type hints y soporte activo. Python 2 sigue apareciendo en sistemas heredados, pero mantenerlo implica costos y riesgos crecientes. La estrategia correcta es comprender las diferencias, proteger el comportamiento con pruebas y migrar hacia una versión soportada de Python 3.






