Python » Miscelánea » Diferencias entre Python 2 y 3: ¿Qué versión debería aprender?

Diferencias entre Python 2 y 3: ¿Qué versión debería aprender?

Actualmente existen dos grandes versiones de Python que son la 2.x y la 3.x. Si quieres aprender a programar con este lenguaje probablemente te preguntes con qué versión deberías empezar. Mi respuesta es con la 3 y veamos por qué. Por un lado la versión 2.7 llegó a su fin de ciclo en el año 2020, y no habrá una versión 2.8. Esto no significa que no se pueda utilizar más, simplemente que no va a recibir más actualizaciones. A parte, las librerías más populares disponibles en Python ya están adaptadas a la versión 3.0 del lenguaje. Por otro lado, también hay que tener en cuenta que quizás acabes trabajando en una empresa que ya tenga código desarrollado en Python 2 que se tenga que mantener; con lo que conocer algunos detalles de la versión 2.x también te puede ser útil. En cualquier caso, pasar de una versión a otra no debería suponer ninguna dificultad ya que en este post vamos a ver cuáles son las principales diferencias entre estas dos versiones.

Imprimir (sentencia print)

Esta sea quizás la diferencia más conocida de todas. En Python 3 la sentencia print() es una función y por tanto hay que encerrar entre paréntesis lo que se quiere imprimir, mientras que con Python 2 los paréntesis no son necesarios.

# Python 2
>>> print 'Programa en Python'
Programa en Python
# Python 3
>>> print('Programa en Python')
Programa en Python

División de números enteros

En Python 2 la división entre números enteros es otro número entero, y para obtener un resultado con decimales el numerador o el denominador tiene que tener también al menos un decimal.

# Python 2
>>> 1/2
0
>>> 1.0/2
0.5
# Python 3
>>> 1/2
0.5
>>> 1.0/2
0.5

El mismo comportamiento truncado puede obtenerse en Python 3 usando //.

# Python 3
>>> 1//2
0

Módulo __future__

Este módulo proporciona retrocompatibilidad de comandos no compatibles entre distintas versiones. Lo podemos usar para adaptar Python 2 a la sintaxis de Python 3. Por ejemplo, en relación con los puntos anteriores nos permite usar print como una función en Python 2.

# Python 2
>>> from __future__ import print_function
>>> print('Programa en Python')
Programa en Python

Otra posibilidad es tener el comportamiento de la división de Python 3 en la versión 2.

# Python 2
>>> from __future__ import division
>>> 1/2
0.5

En este enlace se describen todos los comandos disponibles con este módulo.

Funciones xrange y range

Las funciones xrange() y range() ayudan a crear listas de enteros que podemos utilizar para realizar bucles for. Las diferencias entre estas dos funciones están fuera del propósito de este post, pero residen en el modo en cómo se generan las listas cosa que tiene un impacto en la memoria utilizada y el tiempo necesario para recorrerlas. Lo que debemos saber en este punto es que xrange() no forma parte de Python 3, y si la intentamos usar en esta versión nos salta una excepción del tipo NameError.

Iterar un diccionario

Para iterar los elementos clave-valor de un diccionario podemos utilizar el método iteritems() o items() en Python 2.

# Python 2
d = {'animal': 'perro', 'vehiculo': 'coche'}
for k,v in d.iteritems():
    print k,':',v
vehiculo : coche
animal : perro

En Python 3 esta operación sólo puede realizarse con el método items(), ya que al usar iteritems() tenemos una excepción del tipo AttributeError.

# Python 3
d = {'animal': 'perro', 'vehiculo': 'coche'}
for k,v in d.iteritems():
    print(k,':',v)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'iteritems'

Del mismo modo, los métodos iterkeys() e itervalues() para iterar las claves y los valores de un diccionario respectivamente no existen en Python 3. En su lugar tenemos que usar los métodos keys() y values().

Función next() y método .next()

Recuperar el siguiente elemento de un iterador puede hacerse tanto con la función integrada next() como con el método .next() en Python 2, mientras que en Python 3 next() sólo puede utilizarse como función.

# Python 2
>>> iterador = (letra for letra in 'python')
>>> next(iterador)
'p'
>>> iterador.next()
'y'

Utilizar next() como método en Python 3 nos da una excepción del tipo AttributeError.

# Python 3
>>> iterador = (letra for letra in 'python')
>>> next(iterador)
'p'
>>> iterador.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'generator' object has no attribute 'next'

Comparación de tipos

Python 2 permite la comparación entre objetos de tipo distinto, sin embargo Python 3 es restrictivo en este aspecto dándonos una excepción del tipo TypeError.

# Python 2
>>> 1 < '1'
True
# Python 3
>>> 1 < '1'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'int' and 'str'

Función input()

La función input() sirve para capturar datos procedentes del teclado. En Python 2 esta función trata los datos tal cual sin realizar ninguna conversión. Por ejemplo, si entramos un número entero, la entrada será de tipo int. Si queremos que la entrada se trate como una cadena, entonces tenemos que usar la función raw_input() ya que ésta convierte los datos a tipo str.

# Python 2
>>> entrada = input('Introduce un número: ')
Introduce un número: 1
>>> type(entrada)
<class 'int'>
>>> entrada = raw_input('Introduce un número: ')
Introduce un número: 1
>>> type(entrada)
<class 'str'>

En Python 3 se ha suprimido la función raw_input(), y su comportamiento lo toma la función input(). Esto facilita el tratamiento de los datos entrados por teclado ya que sabemos de antemano que siempre serán strings.

# Python 3
>>> entrada = input('Introduce un número: ')
Introduce un número: 1
>>> type(entrada)
<class 'str'>

Cadenas de texto Unicode

En Python 2 las cadenas de texto (tipo str) están codificadas en formato ASCII con lo que cada carácter sólo requiere 7 bits de información. Por otro lado, las cadenas de texto codificadas en bytes requieren 8 bits de información. Por lo tanto, sólo es posible combinar ambos tipos cuando la representación en bytes sólo contiene caracteres ASCII.

En Python 3 todas las cadenas de texto son Unicode (8 bits). Éstas pueden almacenarse como texto (tipo str) o como datos binarios (tipo bytes), siendo imposible combinar ambos tipos ya que nos da una excepción TypeError.

# Python 3
>>> a = 'Hola'
>>> type(a)
<class 'str'>
>>> b = b'mundo'
>>> type(b)
<class 'bytes'>
>>> a + b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "bytes") to str

Aunque existen otras diferencias entre ambas versiones, en este post hemos visto cuáles son las principales. Si quieres una descripción detallada (en inglés) de todas las diferencias puedes consultar la documentación oficial.

Foto del autor

Albert Brugués

Soy doctor en informática médica y un apasionado de la tecnología y las nuevas oportunidades que brinda. Más en particular me encanta la inteligencia artificial y el desarrollo web. En este blog pretendo compartir los conocimientos de Python que he ido adquiriendo a lo largo de los años.

6 comentarios en «Diferencias entre Python 2 y 3: ¿Qué versión debería aprender?»

  1. interesante. tengo que pasar de 2 a 3 y siempre he tenido miedo de enredarme en tonterias que hacen perder tiempo pero no es asi. estoy seguro que le vendrá bien a mis programas en py 27 “refrescarse” en los módulos de py 3. gracias por el dato de la pag original con todos los cambios ,,,, la vamos a leer

    Responder
  2. Una pregunta. Respecto al tratamiento de ficheros de texto en la versión 3 yo pongo algo del tipo manejador = open (r”ruta”,”w”,enconding=UTF-8). Así puedo meter acentos sin problemas. ¿cómo hago esto en la versión 2? Muchísimas gracias por su ayuda

    Responder
    • Hola Carlos, si usas Python 2 y quieres guardar caracteres con acentos en un fichero de texto, prueba lo siguiente:
      # — coding: utf-8 —

      with open(“acentos.txt”, “w”) as fichero:
      fichero.write(“áéíóú”)

      Responder

Deja un comentario