Qué hay de nuevo en Python 3.1
******************************

Autor:
   Raymond Hettinger

Este artículo explica las nuevas características de Python 3.1, en
comparación con 3.0. Python 3.1 se lanzó el 27 de junio de 2009.


PEP 372: Diccionarios ordenados
===============================

Los diccionarios de Python normales iteran sobre los pares clave/valor
en orden arbitrario. A través de los años, varios autores han escrito
implementaciones alternativas que recuerdan el orden en el que se
insertaron originalmente las claves. Basándose en las experiencias de
esas implementaciones, una nueva clase "collections.OrderedDict" ha
sido introducida.

La API de OrderedDict es sustancialmente la misma que la de los
diccionarios normales, pero iterará sobre las claves y los valores en
un orden garantizado, dependiendo de cuándo se insertó una clave por
primera vez.  Si una nueva entrada sobrescribe una entrada existente,
la posición de inserción original se deja sin cambios.  Eliminar una
entrada y volver a insertarla la moverá hasta el final.

La biblioteca estándar ahora admite el uso de diccionarios ordenados
en varios módulos. El módulo "configparser" los usa por defecto. Esto
permite leer, modificar y volver a escribir los archivos de
configuración en su orden original. El método *_asdict()* para
"collections.namedtuple()" ahora devuelve un diccionario ordenado con
los valores que aparecen en el mismo orden que los índices de tupla
subyacentes. El módulo "json" se está construyendo con un
*object_pairs_hook* para permitir que el decodificador construya
OrderedDicts. También se agregó soporte para herramientas de terceros
como PyYAML.

Ver también:

  **PEP 372** - Diccionarios ordenados
     PEP escrito por Armin Ronacher y Raymond Hettinger.
     Implementación escrita por Raymond Hettinger.

Dado que un diccionario ordenado recuerda su orden de inserción, se
puede utilizar junto con la ordenación para crear un diccionario
ordenado:

   >>> # diccionario regular sin clasificar
   >>> d = {'banana': 3, 'manzana':4, 'pera': 1, 'naranja': 2}

   >>> # diccionario ordenado por clave
   >>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
   OrderedDict([('manzana', 4), ('banana', 3), ('naranja', 2), ('pera', 1)])

   >>> # diccionario ordenado por valor
   >>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
   OrderedDict([('pera', 1), ('naranja', 2), ('banana', 3), ('manzana', 4)])

   >>> # diccionario ordenado por longitud de la clave cadena
   >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
   OrderedDict([('pera', 1), ('manzana', 4), ('naranja', 2), ('banana', 3)])

Los nuevos diccionarios ordenados mantienen su orden de clasificación
cuando se eliminan entradas, pero cuando se agregan nuevas claves,
estas se agregan al final y no se mantiene el orden.


PEP 378: Especificador de formato para el separador de miles
============================================================

La función incorporada "format()" y el método "str.format()" usan un
mini-lenguaje que ahora incluye una forma simple, que no tiene en
cuenta la configuración regional, de formatear un número con un
separador de miles. Eso proporciona una manera de humanizar la salida
de un programa, mejorando su apariencia profesional y legibilidad:

   >>> formato(1234567, ',d')
   '1,234,567'
   >>> formato(1234567.89, ',.2f')
   '1,234,567.89'
   >>> formato(12345.6 + 8901234.12j, ',f')
   '12,345.600000+8,901,234.120000j'
   >>> formato(Decimal('1234567.89'), ',f')
   '1,234,567.89'

Los tipos soportados son "int", "float", "complex" y
"decimal.Decimal".

Se está discutiendo cómo especificar separadores alternativos como
puntos, espacios, apóstrofos o guiones bajos. Las aplicaciones que
reconocen la configuración regional deben usar el especificador de
formato *n* existente, que ya es compatible con el separadores de
miles.

Ver también:

  **PEP 378** - Especificador de formato para el separador de miles
     PEP escrito por Raymond Hettinger e implementado por Eric Smith y
     Mark Dickinson.


Otros cambios del lenguaje
==========================

Algunos cambios pequeños en el núcleo del lenguaje Python son:

* Los directorios y archivos zip que contienen un archivo
  "__main__.py" pueden ahora ser ejecutados directamente pasando su
  nombre al intérprete. El directorio/archivo zip es automáticamente
  insertado como la primera entrada en sys.path.  (Sugerencia y parche
  inicial por Andy Chu; parche revisado por Phillip J. Eby y Nick
  Coghlan; bpo-1739468.)

* El tipo "int()" ganó un método "bit_length" que retorna el número de
  bits necesarios para representar sus argumentos en binario:

     >>> n = 37
     >>> bin(37)
     '0b100101'
     >>> n.bit_length()
     6
     >>> n = 2**123-1
     >>> n.bit_length()
     123
     >>> (n+1).bit_length()
     124

  (Contribución de Fredrik Johansson, Victor Stinner, Raymond
  Hettinger y Mark Dickinson; bpo-3439.)

* Los campos en las cadenas de formato de "format()" ahora pueden ser
  automáticamente numerados:

     >>> 'Señor {} de {}'.format('Gallahad', 'Camelot')
     'Sir Gallahad de Camelot'

  Anteriormente, la cadena requería campos numerados como: "'Sir {0}
  of {1}'".

  (Contribución de Eric Smith; bpo-5237.)

* La función "string.maketrans()" ha quedado obsoleta y se ha
  reemplazado por nuevos métodos estáticos, "bytes.maketrans()" y
  "bytearray.maketrans()". Este cambio resuelve la confusión sobre qué
  tipos eran compatibles con el módulo "string". Ahora, "str", "bytes"
  y "bytearray" tienen sus propios métodos **maketrans** y
  **translate** con tablas de traducción intermedias del tipo
  adecuado.

  (Contribución de Georg Brandl; bpo-5675.)

* La sintaxis de la sentencia "with" ahora permite múltiples gestores
  de contexto en una sola declaración:

     >>> con open('mylog.txt') como archivo de entrada, open('a.out', 'w') como archivo de salida:
     ... para línea en archivo de entrada:
     ... si '<critical>' está en línea:
     ... archivo de salida.write(línea)

  Con la nueva sintaxis, la función "contextlib.nested()" ya no es
  necesaria y ahora está obsoleta.

  (Contribución de Georg Brandl y Mattias Brändström; appspot issue
  53094.)

* "round(x, n)" ahora retorna un número entero si *x* es un entero.
  Anteriormente retornaba un número flotante:

     >>> redondear(1123, -2)
     1100

  (Contribución de Mark Dickinson; bpo-4707.)

* Python ahora utiliza el algoritmo de David Gay para encontrar la
  representación de punto flotante más corta que no cambia su valor.
  Esto debería ayudar a mitigar parte de la confusión que rodea a los
  números binarios de punto flotante.

  La importancia se aprecia fácilmente con un número como "1.1", que
  no tiene un equivalente exacto en coma flotante binaria. Como no hay
  un equivalente exacto, una expresión como "float('1.1')" se evalúa
  como el valor representable más cercano, que es
  "0x1.199999999999ap+0" en hexadecimal o
  "1.100000000000000088817841970012523233890533447265625" en decimal.
  Ese valor más cercano se utilizó y todavía se utiliza en cálculos de
  coma flotante posteriores.

  Lo nuevo es cómo se muestra el número. Anteriormente, Python
  utilizaba un enfoque simple. El valor de "repr(1.1)" se calculaba
  como "format(1.1, '.17g')", que se evaluaba como
  "'1.1000000000000001'". La ventaja de utilizar 17 dígitos era que
  dependía de las garantías IEEE-754 para asegurar que
  "eval(repr(1.1))" regresaría exactamente a su valor original. La
  desventaja es que muchas personas encontraron que el resultado era
  confuso (confundiendo las limitaciones intrínsecas de la
  representación binaria de punto flotante con un problema del propio
  Python).

  El nuevo algoritmo para "repr(1.1)" es más inteligente y retorna
  "'1.1'". Efectivamente, busca todas las representaciones de cadenas
  equivalentes (las que se almacenan con el mismo valor flotante
  subyacente) y retorna la representación más corta.

  El nuevo algoritmo tiende a emitir representaciones más limpias
  cuando es posible, pero esto no cambia los valores subyacentes.  Por
  lo tanto, todavía se da el caso "1.1 + 2.2 != 3.3", aún cuando las
  representaciones puedan sugerir lo contrario.

  El nuevo algoritmo depende de ciertas características de la
  implementación de punto flotante subyacente. Si no se encuentran las
  características requeridas, se seguirá utilizando el algoritmo
  antiguo. Además, los protocolos de pickle de texto garantizan la
  portabilidad entre plataformas mediante el uso del algoritmo
  antiguo.

  (Contribución de Eric Smith y Mark Dickinson; bpo-1580)


Módulos nuevos, mejorados y obsoletos
=====================================

* Se ha añadido una clase "collections.Counter" para admitir el
  recuento conveniente de elementos únicos en una secuencia o una
  iteración:

     >>> Contador(['rojo', 'azul', 'rojo', 'verde', 'azul', 'azul'])
     Contador({'azul': 3, 'rojo': 2, 'verde': 1})

  (Contribución de Raymond Hettinger; bpo-1696199.)

* Se ha añadido un nuevo módulo "tkinter.ttk" para acceder al conjunto
  de widgets temáticos de Tk. La idea básica de ttk es separar, dentro
  de lo posible, el código que implementa el comportamiento de un
  widget del código que implementa su apariencia.

  (Contribución de Guilherme Polo; bpo-2983.)

* Las clases "gzip.GzipFile" y "bz2.BZ2File" ahora admiten el
  protocolo de gestión de contexto:

     >>> # Cerrar automáticamente el archivo después de escribir
     >>> con gzip.GzipFile(filename, "wb") como f:
     ... f.write(b"xxx")

  (Contribución de Antoine Pitrou.)

* El módulo "decimal" ahora admite métodos para crear un objeto
  decimal de un "float" binario.  La conversión es exacta pero puede
  ser a veces una sorpresa:

     >>> Decimal.from_float(1.1)
     Decimal('1.100000000000000088817841970012523233890533447265625')

  El resultado decimal largo muestra la fracción binaria real que se
  almacena para *1.1*. La fracción tiene muchos dígitos porque *1.1*
  no se puede representar exactamente en binario.

  (Contribución de Raymond Hettinger y Mark Dickinson.)

* El módulo "itertools" desarrolló dos nuevas funciones.  La función
  "itertools.combinations_with_replacement()" es una de las cuatro
  para generar combinatorias que incluyen permutaciones y productos
  cartesianos.  La función "itertools.compress()" imita su homónimo de
  APL.  Además, la función existente "itertools.count()" tiene ahora
  un argumento *step* opcional y puede aceptar cualquier tipo de
  secuencia de conteo, incluyendo "fractions.Fraction" y
  "decimal.Decimal":

     >>> [p+q para p,q en combinaciones_con_reemplazo('LOVE', 2)]
     ['LL', 'LO', 'LV', 'LE', 'OO', 'OV', 'OE', 'VV', 'VE', 'EE']

     >>> lista(comprimir(datos=rango(10), selectores=[0,0,1,1,0,1,0,1,0,0]))
     [2, 3, 5, 7]

     >>> c = conteo(inicio=Fracción(1,2), paso=Fracción(1,6))
     >>> [siguiente(c), siguiente(c), siguiente(c), siguiente(c)]
     [Fracción(1, 2), Fracción(2, 3), Fracción(5, 6), Fracción(1, 1)]

  (Contribución de Raymond Hettinger.)

* "collections.namedtuple()" ahora admite un argumento de palabra
  clave *rename* que permite que los campos de nombre inválidos se
  conviertan automáticamente en nombres posicionados de la forma _0,
  _1, etc.  Esto es de utilidad cuando los nombres del campo están
  siendo creados por una fuente externa como un encabezado CSV, una
  lista de campos SQL, o la entrada del usuario:

     >>> consulta = entrada()
     SELECT región, departamento, count(*) FROM main GROUPBY region, dept

     >>> cursor.execute(query)
     >>> query_fields = [desc[0] for desc in cursor.description]
     >>> UserQuery = namedtuple('UserQuery', query_fields, rename=True)
     >>> pprint.pprint([UserQuery(*row) para la fila en el cursor])
     [UserQuery(región='Sur', departamento='Envíos', _2=185),
     UserQuery(región='Norte', departamento='Contabilidad', _2=37),
     UserQuery(región='Oeste', departamento='Ventas', _2=419)]

  (Contribución de Raymond Hettinger; bpo-1818.)

* Las funciones "re.sub()", "re.subn()" y "re.split()" ahora admiten
  un parámetro *flags*.

  (Contribución de Gregory Smith.)

* El módulo "logging" ahora implementa una clase simple
  "logging.NullHandler" para aplicaciones que no utilizan el registro
  pero llaman al código de una biblioteca que si lo hace.  La
  configuración de un controlador nulo suprimirá las advertencias
  falsas como "No handlers could be found for logger foo":

     >>> h = registro.NullHandler()
     >>> registro.getLogger("foo").addHandler(h)

  (Contribución de Vinay Sajip; bpo-4384).

* El módulo "runpy" que admite el modificador de línea de comando "-m"
  ahora admite la ejecución de paquetes al buscar y ejecutar un
  submódulo "__main__" cuando se proporciona un nombre de paquete.

  (Contribución de Andi Vajda; bpo-4195.)

* El módulo "pdb" puede ahora acceder y mostrar el código fuente
  cargado a través de "zipimport" (o cualquier otro cargador conforme
  **PEP 302**).

  (Contribución de Alexander Belopolsky; bpo-4201.)

* Los objetos "functools.partial" pueden ser ahora serializados
  (*pickled*).

   (Sugerido por Antoine Pitrou y Jesse Noller.  Implementado por Jack
   Diederich; bpo-5228.)

* Se agrega temas de ayuda "pydoc" para símbolos de modo que
  "help('@')" funcione como se espera en un entorno interactivo.

  (Contribución de David Laban; bpo-4739.)

* El módulo "unittest" ahora admite saltear pruebas individuales o
  clases de pruebas. Y admite marcar una prueba como una falla
  esperada, una prueba que se sabe que está rota, pero que no debe
  contarse como una falla en un TestResult:

     clase TestGizmo(unittest.TestCase):

     @unittest.skipUnless(sys.platform.startswith("win"), "requiere Windows")
     def test_gizmo_on_windows(self):
     ...

     @unittest.expectedFailure
     def test_gimzo_without_required_library(self):
     ...

  Además, se han creado pruebas de excepciones para trabajar con
  gestores de contexto usando la declaración "with":

     def test_division_by_zero(self):
     con self.assertRaises(ZeroDivisionError):
     x / 0

  Además, se agregaron varios métodos de afirmación nuevos, incluidos
  "assertSetEqual()", "assertDictEqual()",
  "assertDictContainsSubset()", "assertListEqual()",
  "assertTupleEqual()", "assertSequenceEqual()",
  "assertRaisesRegexp()", "assertIsNone()" y "assertIsNotNone()".

  (Contribución de Benjamin Peterson y Antoine Pitrou.)

* El módulo "io" tiene tres nuevas constantes para el método "seek()":
  "SEEK_SET", "SEEK_CUR" y "SEEK_END".

* La tupla "sys.version_info" ahora es una tupla con nombre:

     >>> sys.version_info
     sys.version_info(mayor=3, menor=1, micro=0, nivel de versión='alfa', serial=2)

  (Contribución de Ross Light; bpo-4285.)

* Los módulos "nntplib" y "imaplib" ahora admiten IPv6.

  (Contribución de Derek Morr; bpo-1655 y bpo-1664.)

* El módulo "pickle" ha sido adaptado para una mejor interoperabilidad
  con 2.x cuando es usado con un protocolo 2 o menor.  La
  reorganización de la biblioteca estándar cambió la referencia formal
  para varios objetos.  Por ejemplo, "__builtin__.set" en Python 2 es
  llamado "builtins.set" en Python 3. Este cambio confundió los
  esfuerzos de compartir datos entre diferentes versiones de Python.
  Pero ahora cuando el protocolo 2 o menor es seleccionado, el pickler
  va a usar automáticamente los nombres antiguos de Python 2 tanto
  para carga como para volcado. Esta reasignación es activada de
  manera predeterminada pero puede ser desactivada con la opción
  *fix_imports*:

     >>> s = {1, 2, 3}
     >>> pickle.dumps(s, protocolo=0)
     b'c__builtin__\nestablecer\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.'
     >>> pickle.dumps(s, protocolo=0, fix_imports=False)
     b'cbuiltins\nestablecer\np0\n((lp1\nL1L\naL2L\naL3L\natp2\nRp3\n.'

  Un efecto secundario, desafortunado pero inevitable, de este cambio
  es que los pickles del protocolo 2 producidos con Python 3.1 no
  serán legibles con Python 3.0. El protocolo de pickle más reciente,
  protocolo 3, debe utilizarse al migrar datos entre implementaciones
  de Python 3.x, ya que no intenta seguir siendo compatible con Python
  2.x.

  (Contribución de Alexandre Vassalotti y Antoine Pitrou, bpo-6137.)

* Se agregó un nuevo módulo, "importlib". Proporciona una
  implementación de referencia de Python completa, portátil y pura de
  la instrucción "import" y su contraparte, la función  "__import__()"
  . Representa un avance sustancial en la documentación y definición
  de las acciones que tienen lugar durante las importaciones.

  (Contribución de Brett Cannon.)


Optimizaciones
==============

Se han agregado importantes mejoras de rendimiento:

* La nueva biblioteca I/O (definida en **PEP 3116**) estaba escrita
  mayormente en Python y rápidamente demostró ser un cuello de botella
  problemático en Python 3.0. En Python 3.1, la biblioteca I/O ha sido
  reescrita enteramente en C y es de 2 a 20 veces más rápida
  dependiendo en la tarea a manejar. La versión puramente en Python
  está aún disponible para fines experimentales a través del módulo
  "_pyio".

  (Contribución de Amaury Forgeot d'Arc y Antoine Pitrou.)

* Se ha añadido una heurística para que el recolector de basura no
  realice el seguimiento de tuplas y diccionarios que contengan solo
  objetos no rastreables. Esto puede reducir el tamaño de las
  colecciones y, por lo tanto, la sobrecarga de recolección de
  elementos no utilizados en programas de larga ejecución, en función
  de su uso particular de los tipos de datos.

  (Contribución de Antoine Pitrou, bpo-4688.)

* Habilitando una opción de configuración llamada "--with-computed-
  gotos" en compiladores que la admiten (en particular: gcc, SunPro,
  icc), el ciclo de evaluación del bytecode se compila con un nuevo
  mecanismo de despacho que proporciona aceleraciones de hasta un 20%
  , dependiendo del sistema, del compilador y del punto de referencia.

  (Contribución de Antoine Pitrou junto con varios otros
  participantes, bpo-4753).

* La decodificación de UTF-8, UTF-16 y LATIN-1 es ahora de dos a
  cuatro veces más rápida.

  (Contribución de Antoine Pitrou y Amaury Forgeot d'Arc, bpo-4868.)

* El módulo "json" ahora tiene una extensión C para mejorar
  sustancialmente su rendimiento. Además, se modificó la API para que
  json funcione solo con "str", no con "bytes". Ese cambio hace que el
  módulo coincida estrechamente con el JSON specification que se
  define en términos de Unicode.

  (Contribución de Bob Ippolito y convertido a Py3.1 por Antoine
  Pitrou y Benjamin Peterson; bpo-4136.)

* La deserialización (*unpickling*) ahora interna los nombres de los
  atributos de los objetos serializados (*pickled*). Esto ahorra
  memoria y permite que los pickles sean más pequeños.

  (Contribución de Jake McGuire y Antoine Pitrou; bpo-5084.)


IDLE
====

* El menú de formato del IDLE ahora proporciona una opción para
  eliminar los espacios en blanco finales de un archivo de código
  fuente.

  (Contribución de Roger D. Serwy; bpo-5150.)


Cambios en la compilación y la API de C
=======================================

Los cambios en el proceso de compilación de Python y en la API C
incluyen:

* Los enteros ahora se almacenan internamente en base 2**15 o en base
  2**30, la base se determina en el momento de la construcción.
  Anteriormente, siempre se almacenaban en base 2**15. El uso de base
  2**30 ofrece mejoras significativas en el rendimiento en máquinas de
  64 bits, pero los resultados de las pruebas comparativas en máquinas
  de 32 bits han sido diversos. Por lo tanto, el valor predeterminado
  es usar base 2**30 en máquinas de 64 bits y base 2**15 en máquinas
  de 32 bits; en Unix, hay una nueva opción de configuración "--
  enable-big-digits" que puede ser usada para sobre escribir este
  valor predeterminado.

  Aparte de las mejoras de rendimiento, este cambio debería ser
  invisible para los usuarios finales, con una excepción: para fines
  de prueba y depuración hay un nuevo "sys.int_info" que proporciona
  información sobre el formato interno, dando el número de bits por
  dígito y el tamaño en bytes del tipo C utilizado para almacenar cada
  dígito:

     >>> import sys
     >>> sys.int_info
     sys.int_info(bits_per_digit=30, sizeof_digit=4)

  (Contribución de Mark Dickinson; bpo-4258.)

* La función "PyLong_AsUnsignedLongLong()" es ahora capaz de manejar
  un *pylong* negativo lanzando una excepción "OverflowError" en lugar
  de "TypeError".

  (Contribución de Mark Dickinson y Lisandro Dalcrin; bpo-5175.)

* "PyNumber_Int()" está ahora obsoleto.  Utilice "PyNumber_Long()" en
  su lugar.

  (Contribución de Mark Dickinson; bpo-4910.)

* Se agregó una nueva función "PyOS_string_to_double()" para
  reemplazar las funciones obsoletas "PyOS_ascii_strtod()" y
  "PyOS_ascii_atof()".

  (Contribución de Mark Dickinson; bpo-5914.)

* Se agregó "PyCapsule" como reemplazo de la API "PyCObject". La
  principal diferencia es que el nuevo tipo tiene una interfaz bien
  definida para pasar información de seguridad de tipado y una firma
  menos complicada para llamar a un destructor. El tipo anterior tenía
  una API problemática y ahora está obsoleto.

  (Contribución de Larry Hastings; bpo-5630.)


Portando a Python 3.1
=====================

Esta sección enumera los cambios descritos anteriormente y otras
correcciones de errores que pueden requerir cambios en su código:

* Las nuevas representaciones de cadenas de punto flotante pueden
  romper las pruebas de documentación existentes. Por ejemplo:

     def e():
         '''Compute the base of natural logarithms.

         >>> e()
         2.7182818284590451

         '''
         return sum(1/math.factorial(x) for x in reversed(range(30)))

     doctest.testmod()

     **********************************************************************
     Failed example:
         e()
     Expected:
         2.7182818284590451
     Got:
         2.718281828459045
     **********************************************************************

* La reasignación automática de nombres en el módulo pickle para el
  protocolo 2 o inferior puede hacer que los pickles de Python 3.1
  sean ilegibles en Python 3.0.  Una solución es usar el protocolo 3.
  Otra solución es establecer la opción *fix_imports* en "False".
  Consulte la discusión anterior para obtener más detalles.
