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

Autor:
   A.M. Kuchling

Este artículo explica las nuevas características de Python 2.5.  La
versión final de Python 2.5 está prevista para agosto de 2006; **PEP
356** describe el cronograma de lanzamiento planificado.

The changes in Python 2.5 are an interesting mix of language and
library improvements. The library enhancements will be more important
to Python's user community, I think, because several widely useful
packages were added.  New modules include ElementTree for XML
processing ("xml.etree.ElementTree"), the SQLite database module
("sqlite3"), and the "ctypes" module for calling C functions.

Los cambios en el lenguaje son de mediana importancia.  Se han añadido
algunas características nuevas y agradables, pero la mayoría de ellas
no son características que vaya a utilizar todos los días. Las
expresiones condicionales fueron finalmente añadidas al lenguaje
usando una nueva sintaxis; ver sección PEP 308: Expresiones
condicionales.  La nueva sentencia '"with"' facilitará la escritura de
código de limpieza (sección PEP 343: La declaración "con).  Ahora se
pueden pasar valores a los generadores (sección PEP 342: Nuevas
funciones del generador).  Las importaciones son ahora visibles como
absolutas o relativas (sección PEP 328: Importaciones absolutas y
relativas).  Se han mejorado algunos casos de manejo de excepciones
(sección PEP 341: Try/except/finally unificados).  Todas estas mejoras
merecen la pena, pero son mejoras de una u otra característica
específica del lenguaje; ninguna de ellas es una modificación amplia
de la semántica de Python.

Además de las adiciones al lenguaje y a la biblioteca, se han
realizado otras mejoras y correcciones de errores en todo el árbol de
código fuente.  Una búsqueda en los registros de cambios del SVN
revela que se aplicaron 353 parches y se corrigieron 458 errores entre
Python 2.4 y 2.5.  (Es probable que ambas cifras estén subestimadas)

Este artículo no pretende ser una especificación completa de las
nuevas características; en su lugar, los cambios se introducen
brevemente utilizando ejemplos útiles.  Para obtener todos los
detalles, siempre debes consultar la documentación de Python 2.5 en
https://docs.python.org. Si quieres entender la implementación
completa y los fundamentos del diseño, consulta el PEP de una nueva
característica en particular.

Son bienvenidos los comentarios, las sugerencias y los informes de
errores para este documento; por favor, envíelos por correo
electrónico al autor o abra un error en el rastreador de errores de
Python.


PEP 308: Expresiones condicionales
==================================

Durante mucho tiempo, la gente ha solicitado una forma de escribir
expresiones condicionales, que son expresiones que devuelven el valor
A o el valor B dependiendo de si un valor booleano es verdadero o
falso.  Una expresión condicional le permite escribir una única
sentencia de asignación que tiene el mismo efecto que la siguiente:

   Si la condición es:
   x = valor_verdadero
   De lo contrario:
   x = valor_falso

Ha habido interminables y tediosas discusiones sobre la sintaxis tanto
en python-dev como en comp.lang.python.  Incluso se llevó a cabo una
votación en la que se descubrió que la mayoría de los votantes querían
expresiones condicionales de alguna forma, pero no había ninguna
sintaxis que fuera preferida por una clara mayoría. Los candidatos
incluían "cond ? true_v : false_v", "if cond then true_v else
false_v", y otras 16 variaciones.

Guido van Rossum eligió finalmente una sintaxis sorprendente:

   x = valor_verdadero si condición de lo contrario valor_falso

La evaluación sigue siendo perezosa como en las expresiones booleanas
existentes, por lo que el orden de evaluación salta un poco.  La
expresión *condición* del medio se evalúa primero, y la expresión
*valor_verdadero* se evalúa sólo si la condición es verdadera.  Del
mismo modo, la expresión *valor_falso* sólo se evalúa cuando la
condición es falsa.

Esta sintaxis puede parecer extraña y retrógrada; ¿por qué la
condición va en el *medio* de la expresión, y no en la parte delantera
como en "c ? x : y" de C?  La decisión se comprobó aplicando la nueva
sintaxis a los módulos de la biblioteca estándar y viendo cómo se leía
el código resultante.  En muchos casos en los que se utiliza una
expresión condicional, un valor parece ser el "caso común" y otro
valor es un "caso excepcional", utilizado sólo en las raras ocasiones
en las que no se cumple la condición.  La sintaxis condicional hace
que este patrón sea un poco más obvio:

   contenido = ((doc + '\n') si doc si no '')

Leo la afirmación anterior en el sentido de que "aquí se asigna a
*contents* un valor de "doc+'\n'"; a veces *doc* está vacío, en cuyo
caso especial se devuelve una cadena vacía"   Dudo que use expresiones
condicionales muy a menudo donde no hay un caso común y no común
claro.

Hubo alguna discusión sobre si el lenguaje debería requerir rodear las
expresiones condicionales con paréntesis.  Se tomó la decisión de *no*
requerir paréntesis en la gramática del lenguaje Python, pero como una
cuestión de estilo creo que siempre deberías usarlos. Considere estas
dos declaraciones:

   # Primera versión: sin paréntesis
   nivel = 1 si se registra, de lo contrario, 0

   # Segunda versión: con paréntesis
   nivel = (1 si se registra, de lo contrario, 0)

En la primera versión, creo que el ojo de un lector podría agrupar la
sentencia en 'nivel = 1', 'si registro', 'si no 0', y pensar que la
condición decide si se realiza la asignación a *nivel*.  La segunda
versión se lee mejor, en mi opinión, porque deja claro que la
asignación se realiza siempre y que se está eligiendo entre dos
valores.

Otra razón para incluir los paréntesis: algunas combinaciones extrañas
de comprensiones de listas y lambdas podrían parecer expresiones
condicionales incorrectas. Véase **PEP 308** para algunos ejemplos.
Si pone paréntesis alrededor de sus expresiones condicionales, no se
encontrará con este caso.

Ver también:

  **PEP 308** - Expresiones condicionales
     PEP escrito por Guido van Rossum y Raymond D. Hettinger;
     implementado por Thomas Wouters.


PEP 309: Aplicación parcial de funciones
========================================

El módulo "functools" está destinado a contener herramientas para la
programación de estilo funcional.

One useful tool in this module is the "partial()" function. For
programs written in a functional style, you'll sometimes want to
construct variants of existing functions that have some of the
parameters filled in.  Consider a Python function "f(a, b, c)"; you
could create a new function "g(b, c)" that was equivalent to "f(1, b,
c)".  This is called "partial function application".

"partial()" takes the arguments "(function, arg1, arg2, ...
kwarg1=value1, kwarg2=value2)".  The resulting object is callable, so
you can just call it to invoke *function* with the filled-in
arguments.

He aquí un pequeño pero realista ejemplo:

   import functools

   def log (message, subsystem):
   "Escribe el contenido de 'message' en el subsistema especificado".
   print '%s: %s' % (subsystem, message)
   ...

   server_log = functools.partial(log, subsystem='server')
   server_log('No se puede abrir el socket')

Here's another example, from a program that uses PyGTK.  Here a
context-sensitive pop-up menu is being constructed dynamically.  The
callback provided for the menu option is a partially applied version
of the "open_item()" method, where the first argument has been
provided.

   ...
   class Application:
       def open_item(self, path):
          ...
       def init (self):
           open_func = functools.partial(self.open_item, item_path)
           popup_menu.append( ("Open", open_func, 1) )

Another function in the "functools" module is the
"update_wrapper(wrapper, wrapped)" function that helps you write well-
behaved decorators.  "update_wrapper()" copies the name, module, and
docstring attribute to a wrapper function so that tracebacks inside
the wrapped function are easier to understand.  For example, you might
write:

   def my_decorator(f):
       def wrapper(*args, **kwds):
           print 'Calling decorated function'
           return f(*args, **kwds)
       functools.update_wrapper(wrapper, f)
       return wrapper

"wraps()" is a decorator that can be used inside your own decorators
to copy the wrapped function's information.  An alternate  version of
the previous example would be:

   def my_decorator(f):
       @functools.wraps(f)
       def wrapper(*args, **kwds):
           print 'Calling decorated function'
           return f(*args, **kwds)
       return wrapper

Ver también:

  **PEP 309** - Aplicación parcial de funciones
     PEP propuesto y escrito por Peter Harris; implementado por Hye-
     Shik Chang y Nick Coghlan, con adaptaciones de Raymond Hettinger.


PEP 314: Metadatos para paquetes de software Python v1.1
========================================================

Some simple dependency support was added to Distutils.  The "setup()"
function now has "requires", "provides", and "obsoletes" keyword
parameters.  When you build a source distribution using the "sdist"
command, the dependency information will be recorded in the "PKG-INFO"
file.

Otro nuevo parámetro de palabra clave es "download_url", que debe
establecerse como una URL para el código fuente del paquete.  Esto
significa que ahora es posible buscar una entrada en el índice de
paquetes, determinar las dependencias de un paquete y descargar los
paquetes necesarios.

   VERSION = '1.0'
   setup(name='PyPackage',
         version=VERSION,
         requires=['numarray', 'zlib (>=1.1.4)'],
         obsoletes=['OldPackage']
         download_url=('http://www.example.com/pypackage/dist/pkg-%s.tar.gz'
                       % VERSION),
        )

Otra nueva mejora en el índice de paquetes de Python en
https://pypi.org es el almacenamiento de archivos fuente y binarios de
un paquete.  El nuevo comando **upload** de Distutils subirá un
paquete al repositorio.

Antes de poder subir un paquete, debes ser capaz de construir una
distribución usando el comando **sdist** de Distutils.  Una vez que
funcione, puedes ejecutar "python setup.py upload" para añadir tu
paquete al archivo PyPI.  Opcionalmente puedes firmar el paquete con
GPG suministrando las opciones "--sign" y "--identity".

La carga de paquetes fue implementada por Martin von Löwis y Richard
Jones.

Ver también:

  **PEP 314** - Metadatos para paquetes de software Python v1.1
     PEP propuesto y redactado por A.M. Kuchling, Richard Jones y Fred
     Drake; aplicado por Richard Jones y Fred Drake.


PEP 328: Importaciones absolutas y relativas
============================================

La parte más sencilla de **PEP 328** se implementó en Python 2.4: los
paréntesis podían utilizarse ahora para encerrar los nombres
importados de un módulo utilizando la sentencia "from ... import ...",
facilitando la importación de muchos nombres diferentes.

La parte más complicada se ha implementado en Python 2.5: la
importación de un módulo puede especificarse para utilizar
importaciones absolutas o relativas al paquete.  El plan es hacer que
las importaciones absolutas sean el valor por defecto en futuras
versiones de Python.

Digamos que tienes un directorio de paquetes como este:

   pkg/
   pkg/__init__.py
   pkg/main.py
   pkg/string.py

This defines a package named "pkg" containing the "pkg.main" and
"pkg.string" submodules.

Consider the code in the "main.py" module.  What happens if it
executes the statement "import string"?  In Python 2.4 and earlier, it
will first look in the package's directory to perform a relative
import, finds "pkg/string.py", imports the contents of that file as
the "pkg.string" module, and that module is bound to the name "string"
in the "pkg.main" module's namespace.

That's fine if "pkg.string" was what you wanted.  But what if you
wanted Python's standard "string" module?  There's no clean way to
ignore "pkg.string" and look for the standard module; generally you
had to look at the contents of "sys.modules", which is slightly
unclean.    Holger Krekel's "py.std" package provides a tidier way to
perform imports from the standard library, "import py;
py.std.string.join()", but that package isn't available on all Python
installations.

Reading code which relies on relative imports is also less clear,
because a reader may be confused about which module, "string" or
"pkg.string", is intended to be used.  Python users soon learned not
to duplicate the names of standard library modules in the names of
their packages' submodules, but you can't protect against having your
submodule's name being used for a new module added in a future version
of Python.

En Python 2.5, puedes cambiar el comportamiento de "import" a
importaciones absolutas usando una directiva "from __future__ import
absolute_import".  Este comportamiento de importación absoluta será el
predeterminado en una versión futura (probablemente Python 2.7).  Una
vez que las importaciones absolutas sean el valor por defecto, "import
string" siempre encontrará la versión de la biblioteca estándar. Se
sugiere que los usuarios comiencen a usar importaciones absolutas
tanto como sea posible, así que es preferible comenzar a escribir "de
pkg import string" en su código.

Las importaciones relativas siguen siendo posibles añadiendo un punto
inicial al nombre del módulo cuando se utiliza la forma "from ...
import":

   # Import names from pkg.string
   from .string import name1, name2
   # Import pkg.string
   from . import string

This imports the "string" module relative to the current package, so
in "pkg.main" this will import *name1* and *name2* from "pkg.string".
Additional leading periods perform the relative import starting from
the parent of the current package.  For example, code in the "A.B.C"
module can do:

   from . import D                 # Imports A.B.D
   from .. import E                # Imports A.E
   from ..F import G               # Imports A.F.G

Los puntos suspensivos no pueden usarse con la forma "importar nombre
de modelo" de la sentencia import, sólo con la forma "de ... import".

Ver también:

  **PEP 328** - Importaciones: Multilínea y Absoluto/Relativo
     PEP escrito por Aahz; implementado por Thomas Wouters.

  https://pylib.readthedocs.io/
     The py library by Holger Krekel, which contains the "py.std"
     package.


PEP 338: Ejecutando Módulos como Scripts
========================================

El conmutador "-m" añadido en Python 2.4 para ejecutar un módulo como
un script ganó algunas habilidades más.  En lugar de estar
implementado en código C dentro del intérprete de Python, el
interruptor ahora utiliza una implementación en un nuevo módulo,
"runpy".

The "runpy" module implements a more sophisticated import mechanism so
that it's now possible to run modules in a package such as
"pychecker.checker". The module also supports alternative import
mechanisms such as the "zipimport" module.  This means you can add a
.zip archive's path to "sys.path" and then use the "-m" switch to
execute code from the archive.

Ver también:

  **PEP 338** - Ejecución de módulos como scripts
     PEP escrito e implementado por Nick Coghlan.


PEP 341: Try/except/finally unificados
======================================

Hasta la versión 2.5 de Python, la sentencia "try" tenía dos
variantes. Podías usar un bloque "finally" para asegurarte de que el
código se ejecutaba siempre, o uno o más bloques "except" para
capturar excepciones específicas.  No podías combinar ambos bloques
"except" y un bloque "finally", porque generar el bytecode correcto
para la versión combinada era complicado y no estaba claro cuál debía
ser la semántica de la sentencia combinada.

Guido van Rossum pasó algún tiempo trabajando con Java, que sí soporta
el equivalente de combinar bloques "except" y un bloque "finally", y
esto aclaró lo que debería significar la declaración.  En Python 2.5,
ahora se puede escribir:

   try:
       block-1 ...
   except Exception1:
       handler-1 ...
   except Exception2:
       handler-2 ...
   else:
       else-block
   finally:
       final-block

The code in *block-1* is executed.  If the code raises an exception,
the various "except" blocks are tested: if the exception is of class
"Exception1", *handler-1* is executed; otherwise if it's of class
"Exception2", *handler-2* is executed, and so forth.  If no exception
is raised, the *else-block* is executed.

No importa lo que haya sucedido previamente, el *bloque final* se
ejecuta una vez que el bloque de código se ha completado y se han
manejado las excepciones planteadas. Incluso si hay un error en un
manejador de excepciones o en el *bloque else* y se lanza una nueva
excepción, el código del *bloque final* se sigue ejecutando.

Ver también:

  **PEP 341** - Unificar try-except y try-finally
     PEP escrito por Georg Brandl; implementación por Thomas Lee.


PEP 342: Nuevas funciones del generador
=======================================

Python 2.5 añade una forma sencilla de pasar valores *a* un generador.
Tal y como se introdujo en Python 2.3, los generadores sólo producen
salida; una vez que se invoca el código de un generador para crear un
iterador, no hay forma de pasar ninguna información nueva a la función
cuando se reanuda su ejecución.  A veces, la capacidad de pasar alguna
información sería útil.  Las soluciones más ingeniosas para esto
incluyen hacer que el código del generador mire a una variable global
y luego cambie el valor de la variable global, o pasar algún objeto
mutable que los llamadores luego modifiquen.

Para refrescar la memoria de los generadores básicos, he aquí un
ejemplo sencillo:

   def counter (maximum):
       i = 0
       while i < maximum:
           yield i
           i += 1

Cuando se llama a "contador(10)", el resultado es un iterador que
devuelve los valores de 0 a 9.  Al encontrar la sentencia "yield", el
iterador devuelve el valor proporcionado y suspende la ejecución de la
función, preservando las variables locales. La ejecución se reanuda en
la siguiente llamada al método "next()" del iterador, retomando
después de la sentencia "yield".

En Python 2.3, "yield" era una declaración; no devolvía ningún valor.
En 2.5, "yield" es ahora una expresión, que devuelve un valor que se
puede asignar a una variable o que se puede operar de otra manera:

   val = (rendimiento i)

Te recomiendo que siempre pongas paréntesis alrededor de una expresión
"yield" cuando estés haciendo algo con el valor devuelto, como en el
ejemplo anterior. Los paréntesis no siempre son necesarios, pero es
más fácil añadirlos siempre en lugar de tener que recordar cuándo son
necesarios.

(**PEP 342** explica las reglas exactas, que consisten en que una
expresión "yield"debe ir siempre entre paréntesis, excepto cuando
ocurre en la expresión de nivel superior en el lado derecho de una
asignación.  Esto significa que puedes escribir "val = yield i" pero
tienes que usar paréntesis cuando hay una operación, como en "val =
(yield i) + 12")

Los valores se envían a un generador llamando a su método
"send(value)".  El código del generador se reanuda y la expresión
"yield" devuelve el *valor* especificado.  Si se llama al método
regular "next()", la expresión "yield" devuelve "None".

Aquí está el ejemplo anterior, modificado para permitir cambiar el
valor del contador interno.

   def counter (maximum):
       i = 0
       while i < maximum:
           val = (yield i)
           # If value provided, change counter
           if val is not None:
               i = val
           else:
               i += 1

Y aquí hay un ejemplo de cambio de contador:

   >>> it = counter(10)
   >>> print it.next()
   0
   >>> print it.next()
   1
   >>> print it.send(8)
   8
   >>> print it.next()
   9
   >>> print it.next()
   Traceback (most recent call last):
     File "t.py", line 15, in ?
       print it.next()
   StopIteration

"yield" will usually return "None", so you should always check for
this case.  Don't just use its value in expressions unless you're sure
that the "send()" method will be the only method used to resume your
generator function.

In addition to "send()", there are two other new methods on
generators:

* "throw(type, value=None, traceback=None)" se utiliza para lanzar una
  excepción dentro del generador; la excepción es lanzada por la
  expresión "yield" donde la ejecución del generador se pausa.

* "close()" raises a new "GeneratorExit" exception inside the
  generator to terminate the iteration.  On receiving this exception,
  the generator's code must either raise "GeneratorExit" or
  "StopIteration".  Catching the "GeneratorExit" exception and
  returning a value is illegal and will trigger a "RuntimeError"; if
  the function raises some other exception, that exception is
  propagated to the caller.  "close()" will also be called by Python's
  garbage collector when the generator is garbage-collected.

  Si necesitas ejecutar código de limpieza cuando se produce un
  "GeneratorExit", te sugiero que utilices un conjunto "try: ...
  finally:" en lugar de atrapar "GeneratorExit".

El efecto acumulativo de estos cambios es que los generadores pasan de
ser productores unidireccionales de información a ser tanto
productores como consumidores.

Los generadores también se convierten en *corutinas*, una forma más
generalizada de subrutinas. Las subrutinas se introducen en un punto y
se salen en otro (la parte superior de la función, y una declaración
"return"), pero las coroutines pueden introducirse, salirse y
reanudarse en muchos puntos diferentes (las declaraciones "yield").
Tendremos que descubrir patrones para usar coroutines de forma
efectiva en Python.

The addition of the "close()" method has one side effect that isn't
obvious. "close()" is called when a generator is garbage-collected, so
this means the generator's code gets one last chance to run before the
generator is destroyed. This last chance means that "try...finally"
statements in generators can now be guaranteed to work; the "finally"
clause will now always get a chance to run.  The syntactic restriction
that you couldn't mix "yield" statements with a "try...finally" suite
has therefore been removed.  This seems like a minor bit of language
trivia, but using generators and "try...finally" is actually necessary
in order to implement the "with" statement described by **PEP 343**.
I'll look at this new statement in the following  section.

Another even more esoteric effect of this change: previously, the
"gi_frame" attribute of a generator was always a frame object. It's
now possible for "gi_frame" to be "None" once the generator has been
exhausted.

Ver también:

  **PEP 342** - Coroutines mediante generadores mejorados
     PEP escrito por Guido van Rossum y Phillip J. Eby; implementado
     por Phillip J. Eby.  Incluye ejemplos de algunos usos más
     sofisticados de los generadores como coroutines.

     Versiones anteriores de estas características fueron propuestas
     en **PEP 288** por Raymond Hettinger y **PEP 325** por Samuele
     Pedroni.

  https://en.wikipedia.org/wiki/Coroutine
     La entrada de Wikipedia para las coroutines.

  https://web.archive.org/web/20160321211320/http://www.sidhe.org/~da
  n/blog/archives/000178.html
     Una explicación de las coroutines desde el punto de vista de
     Perl, escrita por Dan Sugalski.


PEP 343: La declaración "con
============================

La sentencia '"with"' aclara el código que antes utilizaba bloques
"try...finally"' para asegurar que se ejecuta el código de limpieza.
En esta sección, hablaré de la sentencia tal y como se utiliza
habitualmente.  En la siguiente sección, examinaré los detalles de la
implementación y mostraré cómo escribir objetos para usar con esta
sentencia.

La declaración '"with"' es una nueva estructura de flujo de control
cuya estructura básica es:

   with expression [as variable]:
       with-block

Se evalúa la expresión y debería dar como resultado un objeto que
admita el protocolo de gestión de contexto (es decir, que tenga los
métodos "__enter__()" y "__exit__()").

El objeto "__enter__()" se llama antes de que se ejecute *with-block*
y, por lo tanto, puede ejecutar el código de configuración. También
puede devolver un valor vinculado al nombre *variable*, si se
proporciona. (Tenga en cuenta que *variable* es *not* al que se le
asigna el resultado de *expression*).

Una vez finalizada la ejecución de *with-block*, se llama al método
"__exit__()" del objeto, incluso si el bloque generó una excepción y,
por lo tanto, puede ejecutar código de limpieza.

Para habilitar la declaración en Python 2.5, debe añadir la siguiente
directiva a su módulo:

   desde __future__ importar con_declaración

La declaración siempre estará habilitada en Python 2.6.

Algunos objetos estándar de Python soportan ahora el protocolo de
gestión de contextos y pueden utilizarse con la sentencia '"with"''.
Los objetos de archivo son un ejemplo:

   with open('/etc/passwd', 'r') as f:
       for line in f:
           print line
           ... more processing code ...

Después de que esta sentencia se haya ejecutado, el objeto archivo en
*f* se habrá cerrado automáticamente, incluso si el bucle "for" lanzó
una excepción a mitad del bloque.

Nota:

  En este caso, *f* es el mismo objeto creado por "open()", porque
  "__enter__()" devuelve *self*.

Los bloqueos y las variables de condición del módulo "threading"
también soportan la sentencia '"with"':

   lock = threading.Lock()
   with lock:
       # Critical section of code
       ...

El bloqueo se adquiere antes de que se ejecute el bloque y siempre se
libera una vez que el bloque se ha completado.

The new "localcontext()" function in the "decimal" module makes it
easy to save and restore the current decimal context, which
encapsulates the desired precision and rounding characteristics for
computations:

   from decimal import Decimal, Context, localcontext

   # Displays with default precision of 28 digits
   v = Decimal('578')
   print v.sqrt()

   with localcontext(Context(prec=16)):
       # All code in this block uses a precision of 16 digits.
       # The original context is restored on exiting the block.
       print v.sqrt()


Redacción de Gestores de Contexto
---------------------------------

Bajo el capó, la sentencia '"with"' es bastante complicada. La mayoría
de la gente sólo utilizará '"with"' en compañía de objetos existentes
y no necesita conocer estos detalles, así que puedes saltarte el resto
de esta sección si quieres.  Los autores de nuevos objetos necesitarán
entender los detalles de la implementación subyacente y deberían
seguir leyendo.

Una explicación de alto nivel del protocolo de gestión del contexto
es:

* La expresión se evalúa y debería generar un objeto denominado
  "administrador de contexto". El administrador de contexto debe tener
  los métodos "__enter__()" y "__exit__()".

* Se llama al método "__enter__()" del administrador de contexto. El
  valor devuelto se asigna a *VAR*. Si no hay ninguna cláusula "'as
  VAR'", el valor simplemente se descarta.

* Se ejecuta el código en *BLOQUE*.

* Si *BLOCK* lanza una excepción, se llama a "__exit__(type, value,
  traceback)" con los detalles de la excepción, los mismos valores
  devueltos por "sys.exc_info()".  El valor de retorno del método
  controla si la excepción se vuelve a lanzar: cualquier valor falso
  vuelve a lanzar la excepción, y "True" resultará en suprimirla.
  Sólo en raras ocasiones querrá suprimir la excepción, porque si lo
  hace el autor del código que contiene la declaración '"with"' nunca
  se dará cuenta de que algo ha ido mal.

* Si *BLOCK* no generó una excepción, aún se llama al método
  "__exit__()", pero *type*, *value* y *traceback* son todos "None".

Pensemos en un ejemplo.  No presentaré un código detallado, sino que
sólo esbozaré los métodos necesarios para una base de datos que
soporte transacciones.

(Para quienes no estén familiarizados con la terminología de las bases
de datos: un conjunto de cambios en la base de datos se agrupa en una
transacción.  Las transacciones pueden ser confirmadas, lo que
significa que todos los cambios se escriben en la base de datos, o
revertidas, lo que significa que todos los cambios se descartan y la
base de datos no se modifica.  Consulte cualquier libro de texto sobre
bases de datos para obtener más información)

Supongamos que hay un objeto que representa una conexión a la base de
datos. Nuestro objetivo será permitir que el usuario escriba código
como este:

   db_connection = DatabaseConnection()
   with db_connection as cursor:
       cursor.execute('insert into ...')
       cursor.execute('delete from ...')
       # ... more operations ...

The transaction should be committed if the code in the block runs
flawlessly or rolled back if there's an exception. Here's the basic
interface for "DatabaseConnection" that I'll assume:

   class DatabaseConnection:
       # Database interface
       def cursor (self):
           "Returns a cursor object and starts a new transaction"
       def commit (self):
           "Commits current transaction"
       def rollback (self):
           "Rolls back current transaction"

El método "__enter__()" es bastante sencillo, ya que solo hay que
iniciar una nueva transacción. Para esta aplicación, el objeto cursor
resultante sería un resultado útil, por lo que el método lo devolverá.
El usuario puede entonces añadir "as cursor" a su declaración '"with"'
para vincular el cursor a un nombre de variable.

   class DatabaseConnection:
       ...
       def __enter__ (self):
           # Code to start a new transaction
           cursor = self.cursor()
           return cursor

El método "__exit__()" es el más complicado porque es donde se debe
realizar la mayor parte del trabajo. El método debe verificar si se
produjo una excepción. Si no hubo excepción, se confirma la
transacción. Si hubo una excepción, se revierte la transacción.

En el código de abajo, la ejecución simplemente caerá al final de la
función, devolviendo el valor por defecto de "None".  "None" es falso,
por lo que la excepción se volverá a lanzar automáticamente.  Si lo
desea, puede ser más explícito y añadir una declaración "return" en el
lugar marcado.

   class DatabaseConnection:
       ...
       def __exit__ (self, type, value, tb):
           if tb is None:
               # No exception, so commit
               self.commit()
           else:
               # Exception occurred, so rollback.
               self.rollback()
               # return False


El módulo contextlib
--------------------

El nuevo módulo "contextlib" proporciona algunas funciones y un
decorador que son útiles para escribir objetos para usar con la
sentencia '"with"'.

The decorator is called "@~contextlib.contextmanager", and lets you
write a single generator function instead of defining a new class.
The generator should yield exactly one value.  The code up to the
"yield" will be executed as the "__enter__()" method, and the value
yielded will be the method's return value that will get bound to the
variable in the '"with"' statement's "as" clause, if any.  The code
after the "yield" will be executed in the "__exit__()" method.  Any
exception raised in the block will be raised by the "yield" statement.

Nuestro ejemplo de base de datos de la sección anterior podría
escribirse utilizando este decorador como:

   from contextlib import contextmanager

   @contextmanager
   def db_transaction (connection):
       cursor = connection.cursor()
       try:
           yield cursor
       except:
           connection.rollback()
           raise
       else:
           connection.commit()

   db = DatabaseConnection()
   with db_transaction(db) as cursor:
       ...

El módulo "contextlib" también tiene una función "anidada(mgr1, mgr2,
...)" que combina varios gestores de contexto para que no sea
necesario escribir sentencias '"with"' anidadas.  En este ejemplo, la
única sentencia '"with`" inicia una transacción de base de datos y
adquiere un bloqueo de hilo:

   lock = threading.Lock()
   con anidado (db_transaction(db), lock) como (cursor, bloqueado):
   ...

Por último, la función "closing(object)" devuelve el *objeto* para que
pueda ser vinculado a una variable, y llama a "object.close" al final
del bloque.

   import urllib, sys
   from contextlib import closing

   with closing(urllib.urlopen('http://www.yahoo.com')) as f:
       for line in f:
           sys.stdout.write(line)

Ver también:

  **PEP 343** - La declaración "con"
     PEP escrito por Guido van Rossum y Nick Coghlan; implementado por
     Mike Bland, Guido van Rossum y Neal Norwitz.  El PEP muestra el
     código generado para una sentencia '"with"', que puede ser útil
     para aprender cómo funciona la sentencia.

  La documentación del módulo "contextlib".


PEP 352: Las excepciones como clases de nuevo estilo
====================================================

Las clases de excepción ahora pueden ser clases de nuevo estilo, no
sólo clases clásicas, y la clase incorporada "Exception" y todas las
excepciones incorporadas estándar ("NameError", "ValueError", etc.)
son ahora clases de nuevo estilo.

La jerarquía de herencia de las excepciones se ha reordenado un poco.
En 2.5, las relaciones de herencia son:

   BaseException       # New in Python 2.5
   |- KeyboardInterrupt
   |- SystemExit
   |- Exception
      |- (all other current built-in exceptions)

Esta reorganización se hizo porque la gente a menudo quiere atrapar
todas las excepciones que indican errores del programa.
"KeyboardInterrupt" y "SystemExit" no son errores, sin embargo, y por
lo general representan una acción explícita como el usuario pulsando
"Control"-"C" o el código llamando a "sys.exit()".  Una simple
"except:" atrapará todas las excepciones, por lo que comúnmente se
necesita listar "KeyboardInterrupt" y "SystemExit" para volver a
lanzarlas.  El patrón habitual es:

   try:
       ...
   except (KeyboardInterrupt, SystemExit):
       raise
   except:
       # Log error...
       # Continue running program...

En Python 2.5, ahora puedes escribir "except Exception" para conseguir
el mismo resultado, capturando todas las excepciones que suelen
indicar errores pero dejando "KeyboardInterrupt" y "SystemExit" en
paz.  Como en versiones anteriores, un "except:" desnudo sigue
capturando todas las excepciones.

El objetivo de Python 3.0 es requerir que cualquier clase lanzada como
excepción derive de "BaseException" o de algún descendiente de
"BaseException", y las futuras versiones de la serie Python 2.x pueden
empezar a imponer esta restricción. Por lo tanto, sugiero que empieces
a hacer que todas tus clases de excepción deriven de "Exception"
ahora.  Se ha sugerido que la forma desnuda "except:" sea eliminada en
Python 3.0, pero Guido van Rossum no ha decidido si hacerlo o no.

El lanzamiento de cadenas como excepciones, como en la declaración
"raise "Error occurred"", está obsoleto en Python 2.5 y provocará una
advertencia.  El objetivo es poder eliminar la función de excepción de
cadena en algunas versiones.

Ver también:

  **PEP 352** - Superclase necesaria para las excepciones
     PEP escrito por Brett Cannon y Guido van Rossum; implementado por
     Brett Cannon.


PEP 353: Uso de ssize_t como tipo de índice
===========================================

Un cambio de gran alcance en la API C de Python, que usa una nueva
definición de tipo "Py_ssize_t" en lugar de int, permitirá que el
intérprete maneje más datos en plataformas de 64 bits. Este cambio no
afecta la capacidad de Python en plataformas de 32 bits.

Varias piezas del intérprete de Python usaban el tipo int de C para
almacenar tamaños o conteos; por ejemplo, la cantidad de elementos en
una lista o tupla se almacenaron en un int. Los compiladores de C para
la mayoría de las plataformas de 64 bits aún definen int como un tipo
de 32 bits, lo que significa que las listas solo pueden contener hasta
"2**31 - 1" = 2147483647 elementos. (En realidad, hay algunos modelos
de programación diferentes que los compiladores de C de 64 bits pueden
usar; consulte https://unix.org/version2/whatsnew/lp64_wp.html para
ver una discusión, pero el modelo más comúnmente disponible deja int
como 32 bits).

Un límite de 2147483647 elementos no importa realmente en una
plataforma de 32 bits porque te quedarás sin memoria antes de alcanzar
el límite de longitud. Cada elemento de la lista requiere espacio para
un puntero, que es de 4 bytes, más espacio para un "PyObject" que
representa el elemento.  2147483647*4 ya son más bytes de los que
puede contener un espacio de direcciones de 32 bits.

Sin embargo, es posible abordar esa cantidad de memoria en una
plataforma de 64 bits. Los punteros para una lista de ese tamaño solo
requerirían 16 GiB de espacio, por lo que no es irrazonable que los
programadores de Python puedan construir listas tan grandes. Por lo
tanto, el intérprete de Python tuvo que cambiarse para usar algún tipo
diferente a int, y este será un tipo de 64 bits en plataformas de 64
bits. El cambio provocará incompatibilidades en las máquinas de 64
bits, por lo que se consideró que valía la pena hacer la transición
ahora, mientras que la cantidad de usuarios de 64 bits aún es
relativamente pequeña. (En 5 o 10 años, es posible que *todo* esté en
máquinas de 64 bits y la transición sería más dolorosa entonces).

Este cambio afecta en mayor medida a los autores de módulos de
extensión de C.   Las cadenas de Python y los tipos contenedores como
las listas y las tuplas utilizan ahora "Py_ssize_t" para almacenar su
tamaño.   Funciones como "PyList_Size()" ahora devuelven "Py_ssize_t".
Por lo tanto, el código de los módulos de extensión puede necesitar
cambiar algunas variables a "Py_ssize_t".

The "PyArg_ParseTuple()" and "Py_BuildValue()" functions have a new
conversion code, "n", for "Py_ssize_t".   "PyArg_ParseTuple()"'s "s#"
and "t#" still output int by default, but you can define the macro
"PY_SSIZE_T_CLEAN" before including "Python.h"  to make them return
"Py_ssize_t".

**PEP 353** tiene una sección sobre directrices de conversión que los
autores de extensiones deberían leer para aprender a soportar
plataformas de 64 bits.

Ver también:

  **PEP 353** - Uso de ssize_t como tipo de índice
     PEP escrito y aplicado por Martin von Löwis.


PEP 357: El método '__index__'
==============================

The NumPy developers had a problem that could only be solved by adding
a new special method, "__index__()".  When using slice notation, as in
"[start:stop:step]", the values of the *start*, *stop*, and *step*
indexes must all be either integers or long integers.  NumPy defines a
variety of specialized integer types corresponding to unsigned and
signed integers of 8, 16, 32, and 64 bits, but there was no way to
signal that these types could be used as slice indexes.

Slicing can't just use the existing "__int__()" method because that
method is also used to implement coercion to integers.  If slicing
used "__int__()", floating-point numbers would also become legal slice
indexes and that's clearly an undesirable behaviour.

Instead, a new special method called "__index__()" was added.  It
takes no arguments and returns an integer giving the slice index to
use.  For example:

   class C:
       def __index__ (self):
           return self.value

El valor devuelto debe ser un entero de Python o un entero largo. El
intérprete comprobará que el tipo devuelto es correcto, y lanza un
"TypeError" si no se cumple este requisito.

A corresponding "nb_index" slot was added to the C-level
"PyNumberMethods" structure to let C extensions implement this
protocol. "PyNumber_Index(obj)" can be used in extension code to call
the "__index__()" function and retrieve its result.

Ver también:

  **PEP 357** - Permitir el uso de cualquier objeto para rebanar
     PEP escrito e implementado por Travis Oliphant.


Otros cambios lingüísticos
==========================

Estos son todos los cambios que Python 2.5 introduce en el núcleo del
lenguaje Python.

* The "dict" type has a new hook for letting subclasses provide a
  default value when a key isn't contained in the dictionary. When a
  key isn't found, the dictionary's "__missing__(key)" method will be
  called.  This hook is used to implement the new "defaultdict" class
  in the "collections" module.  The following example defines a
  dictionary  that returns zero for any missing key:

     class zerodict (dict):
         def __missing__ (self, key):
             return 0

     d = zerodict({1:1, 2:2})
     print d[1], d[2]   # Prints 1, 2
     print d[3], d[4]   # Prints 0, 0

* Tanto las cadenas de 8 bits como las de Unicode tienen nuevos
  métodos "partition(sep)" y "rpartition(sep)" que simplifican un caso
  de uso común.

  El método "find(S)" se utiliza a menudo para obtener un índice que
  luego se utiliza para cortar la cadena y obtener las piezas que
  están antes y después del separador. El método "partition(sep)"
  condensa este patrón en una sola llamada al método que devuelve una
  tripleta que contiene la subcadena antes del separador, el propio
  separador y la subcadena después del separador.  Si no se encuentra
  el separador, el primer elemento de la tupla es la cadena completa y
  los otros dos elementos están vacíos.  "rpartition(sep)" también
  devuelve una tupla de 3 elementos, pero empieza a buscar desde el
  final de la cadena; la "r" significa "al revés".

  Algunos ejemplos:

     >>> ('http://www.python.org').partition('://')
     ('http', '://', 'www.python.org')
     >>> ('file:/usr/share/doc/index.html').partition('://')
     ('file:/usr/share/doc/index.html', '', '')
     >>> (u'Subject: a quick question').partition(':')
     (u'Subject', u':', u' a quick question')
     >>> 'www.python.org'.rpartition('.')
     ('www.python', '.', 'org')
     >>> 'www.python.org'.rpartition(':')
     ('', '', 'www.python.org')

  (Implementado por Fredrik Lundh tras una sugerencia de Raymond
  Hettinger)

* The "startswith()" and "endswith()" methods of string types now
  accept tuples of strings to check for.

     def is_image_file (nombre_archivo):
     return nombre_archivo.endswith(('.gif', '.jpg', '.tiff'))

  (Implementado por Georg Brandl tras una sugerencia de Tom Lynn)

* The "min()" and "max()" built-in functions gained a "key" keyword
  parameter analogous to the "key" argument for "sort()".  This
  parameter supplies a function that takes a single argument and is
  called for every value in the list; "min()"/"max()" will return the
  element with the smallest/largest return value from this function.
  For example, to find the longest string in a list, you can do:

     L = ['medium', 'longest', 'short']
     # Prints 'longest'
     print max(L, key=len)
     # Prints 'short', because lexicographically 'short' has the largest value
     print max(L)

  (Contribución de Steven Bethard y Raymond Hettinger)

* Dos nuevas funciones incorporadas, "any()" y "all()", evalúan si un
  iterador contiene algún valor verdadero o falso. "any()" devuelve
  "True" si cualquier valor devuelto por el iterador es verdadero; en
  caso contrario devolverá "False". "all()" devuelve "True" sólo si
  todos los valores devueltos por el iterador se evalúan como
  verdaderos. (Sugerido por Guido van Rossum, e implementado por
  Raymond Hettinger)

* The result of a class's "__hash__()" method can now be either a long
  integer or a regular integer.  If a long integer is returned, the
  hash of that value is taken.  In earlier versions the hash value was
  required to be a regular integer, but in 2.5 the "id()" built-in was
  changed to always return non-negative numbers, and users often seem
  to use "id(self)" in "__hash__()" methods (though this is
  discouraged).

* ASCII es ahora la codificación por defecto para los módulos.  Ahora
  es un error de sintaxis si un módulo contiene literales de cadena
  con caracteres de 8 bits pero no tiene una declaración de
  codificación.  En Python 2.4 esto provocaba una advertencia, no un
  error de sintaxis.  Vea en **PEP 263** cómo declarar la codificación
  de un módulo; por ejemplo, puede añadir una línea como ésta cerca de
  la parte superior del fichero fuente:

     #-*- coding: latin1 -*-

* Una nueva advertencia, "UnicodeWarning", se activa cuando se intenta
  comparar una cadena Unicode y una cadena de 8 bits que no se puede
  convertir a Unicode utilizando la codificación ASCII por defecto.
  El resultado de la comparación es falso:

     >>> chr(128) == unichr(128)   # Can't convert chr(128) to Unicode
     __main__:1: UnicodeWarning: Unicode equal comparison failed
       to convert both arguments to Unicode - interpreting them
       as being unequal
     False
     >>> chr(127) == unichr(127)   # chr(127) can be converted
     True

  Anteriormente, esto lanzaba una excepción "UnicodeDecodeError", pero
  en 2.5 esto podía dar lugar a problemas desconcertantes al acceder a
  un diccionario.  Si se buscaba "unichr(128)" y se utilizaba
  "chr(128)" como clave, se producía una excepción
  "UnicodeDecodeError".  Otros cambios en la versión 2.5 hicieron que
  esta excepción se lanzara en lugar de ser suprimida por el código de
  "dictobject.c" que implementa los diccionarios.

  Lanzar una excepción para tal comparación es estrictamente correcto,
  pero el cambio podría haber roto el código, así que en su lugar se
  introdujo "UnicodeWarning".

  (Implementado por Marc-André Lemburg.)

* Un error que a veces cometen los programadores de Python es
  olvidarse de incluir un módulo "__init__.py" en el directorio de un
  paquete. Depurar este error puede ser confuso, y normalmente
  requiere ejecutar Python con el modificador "-v" para registrar
  todas las rutas buscadas. En Python 2.5, una nueva advertencia
  "ImportWarning" se activa cuando una importación habría recogido un
  directorio como paquete pero no se encontró ningún "__init__.py".
  Esta advertencia se ignora silenciosamente por defecto; proporcione
  la opción "-Wd" cuando ejecute el ejecutable de Python para mostrar
  el mensaje de advertencia. (Implementado por Thomas Wouters)</-W>

* La lista de clases base en una definición de clase ahora puede estar
  vacía.   Como ejemplo, esto es ahora legal:

     clase C():
         pass

  (Implementado por Brett Cannon.)


Cambios en el intérprete interactivo
------------------------------------

En el intérprete interactivo, "quit" y "exit" han sido durante mucho
tiempo cadenas para que los nuevos usuarios obtengan un mensaje algo
útil cuando intenten salir:

   >>> salir
   'Utilice Ctrl-D (es decir, EOF) para salir.'

En Python 2.5, "quit" y "exit" son ahora objetos que siguen
produciendo representaciones de cadena de sí mismos, pero también son
invocables. Los novatos que prueben "quit()" o "exit()" ahora saldrán
del intérprete como se espera.  (Implementado por Georg Brandl.)

El ejecutable de Python ahora acepta las opciones largas estándar "--
help" y "--version"; en Windows, también acepta la opción "/?" para
mostrar un mensaje de ayuda. (Implementado por Georg Brandl)


Optimizaciones
--------------

Varias de las optimizaciones se desarrollaron en el sprint
NeedForSpeed, un evento celebrado en Reikiavik, Islandia, del 21 al 28
de mayo de 2006. El sprint se centró en las mejoras de velocidad de la
implementación de CPython y fue financiado por EWT LLC con el apoyo
local de CCP Games.  Las optimizaciones añadidas en este sprint están
especialmente marcadas en la siguiente lista.

* Cuando se introdujeron en Python 2.4, los tipos incorporados "set" y
  "frozenset" se construyeron sobre el tipo diccionario de Python.
  En 2.5 la estructura de datos interna se ha personalizado para
  implementar conjuntos, y como resultado los conjuntos utilizarán un
  tercio menos de memoria y son algo más rápidos. (Implementado por
  Raymond Hettinger)

* Se ha mejorado la velocidad de algunas operaciones Unicode, como la
  búsqueda de subcadenas, la división de cadenas y la codificación y
  decodificación de mapas de caracteres. (Las mejoras en la búsqueda
  de subcadenas y la división fueron añadidas por Fredrik Lundh y
  Andrew Dalke en el sprint NeedForSpeed. Los mapas de caracteres
  fueron mejorados por Walter Dörwald y Martin von Löwis)

* La función "long(str, base)" es ahora más rápida en cadenas de
  dígitos largos porque se calculan menos resultados intermedios.  El
  máximo es para cadenas de alrededor de 800-1000 dígitos, donde la
  función es 6 veces más rápida. (Aportado por Alan McIntyre y
  comprometido en el sprint NeedForSpeed)

* It's now illegal to mix iterating over a file  with "for line in
  file" and calling  the file object's
  "read()"/"readline()"/"readlines()" methods.  Iteration uses an
  internal buffer and the  "read*()" methods don't use that buffer.
  Instead they would return the data following the buffer, causing the
  data to appear out of order.  Mixing iteration and these methods
  will now trigger a "ValueError" from the "read*()" method.
  (Implemented by Thomas Wouters.)

* El módulo "struct" ahora compila cadenas de formato de estructura en
  una representación interna y almacena en caché esta representación,
  lo que supone una mejora del 20% s. (Contribuido por Bob Ippolito en
  el sprint NeedForSpeed)

* El módulo "re" obtuvo un 1 o 2% s de velocidad al cambiar a las
  funciones asignadoras de Python en lugar de las "malloc()" y
  "free()" del sistema. (Contribuido por Jack Diederich en el sprint
  NeedForSpeed)

* El optimizador de la mirilla del generador de código realiza ahora
  un simple plegado de constantes en las expresiones.  Si escribes
  algo como "a = 2+3", el generador de código hará la aritmética y
  producirá el código correspondiente a "a = 5".  (Propuesto e
  implementado por Raymond Hettinger)

* Las llamadas a funciones son ahora más rápidas porque los objetos de
  código guardan ahora el último fotograma terminado (un "fotograma
  zombi") en un campo interno del objeto de código, reutilizándolo la
  próxima vez que se invoque el objeto de código.  (Parche original de
  Michael Hudson, modificado por Armin Rigo y Richard Jones;
  confirmado en el sprint NeedForSpeed)  Los objetos marco son también
  ligeramente más pequeños, lo que puede mejorar la localidad de la
  caché y reducir un poco el uso de la memoria.  (Contribución de Neal
  Norwitz)

* Las excepciones incorporadas en Python son ahora clases de nuevo
  estilo, un cambio que acelera considerablemente la instanciación.
  El manejo de excepciones en Python 2.5 es, por tanto, un 30% f más
  rápido que en 2.4. (Contribución de Richard Jones, Georg Brandl y
  Sean Reifschneider en el sprint NeedForSpeed)

* Importing now caches the paths tried, recording whether  they exist
  or not so that the interpreter makes fewer  "open()" and "stat()"
  calls on startup. (Contributed by Martin von Löwis and Georg
  Brandl.)


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

La biblioteca estándar ha recibido muchas mejoras y correcciones de
errores en Python 2.5. Aquí hay una lista parcial de los cambios más
notables, ordenados alfabéticamente por el nombre del módulo. Consulte
el archivo "Misc/NEWS" en el árbol de fuentes para obtener una lista
más completa de los cambios, o busque en los registros de SVN para
obtener todos los detalles.

* El módulo "audioop" ahora admite la codificación a-LAW y se ha
  mejorado el código para la codificación u-LAW. (Contribución de Lars
  Immisch).

* The "codecs" module gained support for incremental codecs.  The
  "codecs.lookup()" function now returns a "CodecInfo" instance
  instead of a tuple. "CodecInfo" instances behave like a 4-tuple to
  preserve backward compatibility but also have the attributes
  "encode", "decode", "incrementalencoder", "incrementaldecoder",
  "streamwriter", and "streamreader".  Incremental codecs  can receive
  input and produce output in multiple chunks; the output is the same
  as if the entire input was fed to the non-incremental codec. See the
  "codecs" module documentation for details. (Designed and implemented
  by Walter Dörwald.)

* The "collections" module gained a new type, "defaultdict", that
  subclasses the standard "dict" type.  The new type mostly behaves
  like a dictionary but constructs a default value when a key isn't
  present, automatically adding it to the dictionary for the requested
  key value.

  The first argument to "defaultdict"'s constructor is a factory
  function that gets called whenever a key is requested but not found.
  This factory function receives no arguments, so you can use built-in
  type constructors such as "list()" or "int()".  For example,  you
  can make an index of words based on their initial letter like this:

     palabras = """Nel mezzo del cammin di nuestra vita
     mi ritrovai per una selva oscura
     che la diritta via era smarrita""".lower().split()

     índice = dictamen predeterminado (lista)

     para w en palabras:
         letra_inicial = w[0]
         índice[letra_inicio].append(w)

  Al imprimir "index" se obtiene la siguiente salida:

     defaultdict(<type 'list'>, {'c': ['cammin', 'che'], 'e': ['era'],
             'd': ['del', 'di', 'diritta'], 'm': ['mezzo', 'mi'],
             'l': ['la'], 'o': ['oscura'], 'n': ['nel', 'nostra'],
             'p': ['per'], 's': ['selva', 'smarrita'],
             'r': ['ritrovai'], 'u': ['una'], 'v': ['vita', 'via']}

  (Contribución de Guido van Rossum.)

* The "deque" double-ended queue type supplied by the "collections"
  module now has a "remove(value)" method that removes the first
  occurrence of *value* in the queue, raising "ValueError" if the
  value isn't found. (Contributed by Raymond Hettinger.)

* Nuevo módulo: El módulo "contextlib" contiene funciones de ayuda
  para usar con la nueva sentencia '"with"'.  Consulte la sección El
  módulo contextlib para obtener más información sobre este módulo.

* New module: The "cProfile" module is a C implementation of  the
  existing "profile" module that has much lower overhead. The module's
  interface is the same as "profile": you run "cProfile.run('main()')"
  to profile a function, can save profile data to a file, etc.  It's
  not yet known if the Hotshot profiler, which is also written in C
  but doesn't match the "profile" module's interface, will continue to
  be maintained in future versions of Python.  (Contributed by Armin
  Rigo.)

  Also, the "pstats" module for analyzing the data measured by the
  profiler now supports directing the output to any file object by
  supplying a *stream* argument to the "Stats" constructor.
  (Contributed by Skip Montanaro.)

* The "csv" module, which parses files in comma-separated value
  format, received several enhancements and a number of bugfixes.  You
  can now set the maximum size in bytes of a field by calling the
  "csv.field_size_limit(new_limit)" function; omitting the *new_limit*
  argument will return the currently set limit.  The "reader" class
  now has a "line_num" attribute that counts the number of physical
  lines read from the source; records can span multiple physical
  lines, so "line_num" is not the same as the number of records read.

  El analizador CSV es ahora más estricto con los campos
  entrecomillados de varias líneas. Anteriormente, si una línea
  terminaba dentro de un campo entre comillas sin un carácter de nueva
  línea final, se insertaba una nueva línea en el campo devuelto. Este
  comportamiento causaba problemas cuando se leían archivos que
  contenían caracteres de retorno de carro dentro de los campos, por
  lo que se cambió el código para devolver el campo sin insertar
  nuevas líneas. Como consecuencia, si las nuevas líneas incrustadas
  dentro de los campos son importantes, la entrada debe dividirse en
  líneas de manera que se conserven los caracteres de nueva línea.

  (Contribución de Skip Montanaro y Andrew McNamara)

* La clase "datetime" del módulo "datetime" tiene ahora un método
  "strptime(string, format)" para analizar cadenas de fechas, aportado
  por Josh Spoerri. Utiliza los mismos caracteres de formato que
  "time.strptime()" y "time.strftime()":

     import datetime as dt

     ts = dt.datetime.strptime('10:13:15 2006-03-07',
                               '%H:%M:%S %Y-%m-%d')

* The "difflib.SequenceMatcher.get_matching_blocks()" method in the
  "difflib" module now guarantees to return a minimal list of blocks
  describing matching subsequences.  Previously, the algorithm would
  occasionally break a block of matching elements into two list
  entries. (Enhancement by Tim Peters.)

* El módulo "doctest" ha ganado una opción "SKIP" que impide que un
  ejemplo se ejecute en absoluto.  Esto está pensado para los
  fragmentos de código que son ejemplos de uso destinados al lector y
  que no son realmente casos de prueba.

  An *encoding* parameter was added to the "testfile()" function and
  the "DocFileSuite" class to specify the file's encoding.  This makes
  it easier to use non-ASCII characters in  tests contained within a
  docstring. (Contributed by Bjorn Tillenius.)

* El paquete "email" ha sido actualizado a la versión 4.0.
  (Contribución de Barry Warsaw.)

* The "fileinput" module was made more flexible. Unicode filenames are
  now supported, and a *mode* parameter that defaults to ""r"" was
  added to the "input()" function to allow opening files in binary or
  *universal newlines* mode.  Another new parameter, *openhook*, lets
  you use a function other than "open()"  to open the input files.
  Once you're iterating over the set of files, the "FileInput"
  object's new "fileno()" returns the file descriptor for the
  currently opened file. (Contributed by Georg Brandl.)

* In the "gc" module, the new "get_count()" function returns a 3-tuple
  containing the current collection counts for the three GC
  generations.  This is accounting information for the garbage
  collector; when these counts reach a specified threshold, a garbage
  collection sweep will be made.  The existing "gc.collect()" function
  now takes an optional *generation* argument of 0, 1, or 2 to specify
  which generation to collect. (Contributed by Barry Warsaw.)

* The "nsmallest()" and  "nlargest()" functions in the "heapq" module
  now support a "key" keyword parameter similar to the one provided by
  the "min()"/"max()" functions and the "sort()" methods.  For
  example:

     >>> import heapq
     >>> L = ["short", 'medium', 'longest', 'longer still']
     >>> heapq.nsmallest(2, L)  # Return two lowest elements, lexicographically
     ['longer still', 'longest']
     >>> heapq.nsmallest(2, L, key=len)   # Return two shortest elements
     ['short', 'medium']

  (Contribución de Raymond Hettinger.)

* La función "itertools.islice()" ahora acepta "None" para los
  argumentos de inicio y paso.  Esto la hace más compatible con los
  atributos de los objetos slice, por lo que ahora se puede escribir
  lo siguiente:

     s = slice(5) # Crear objeto slice
     itertools.islice(iterable, s.start, s.stop, s.step)

  (Contribución de Raymond Hettinger.)

* The "format()" function in the "locale" module has been modified and
  two new functions were added, "format_string()" and "currency()".

  El parámetro *val* de la función "format()" podía ser antes una
  cadena siempre que no apareciera más de un especificador %char;
  ahora el parámetro debe ser exactamente un especificador %char sin
  texto alrededor.  También se ha añadido un parámetro opcional
  *monetario* que, si es "Verdadero", utilizará las reglas de la
  configuración regional para formatear la moneda al colocar un
  separador entre grupos de tres dígitos.

  To format strings with multiple %char specifiers, use the new
  "format_string()" function that works like "format()" but also
  supports mixing %char specifiers with arbitrary text.

  A new "currency()" function was also added that formats a number
  according to the current locale's settings.

  (Contribución de Georg Brandl.)

* The "mailbox" module underwent a massive rewrite to add the
  capability to modify mailboxes in addition to reading them.  A new
  set of classes that include "mbox", "MH", and "Maildir" are used to
  read mailboxes, and have an "add(message)" method to add messages,
  "remove(key)" to remove messages, and "lock()"/"unlock()" to
  lock/unlock the mailbox. The following example converts a maildir-
  format mailbox into an mbox-format one:

     importar buzón

     # 'factory=None' utiliza email.Message.Message como la clase que representa
     # los mensajes individuales.
     src = mailbox.Maildir('maildir', factory=None)
     dest = mailbox.mbox('/tmp/mbox')

     para msg en src:
     dest.add(msg)

  (Contribución de Gregory K. Johnson.  La financiación fue
  proporcionada por el Summer of Code 2005 de Google)

* Nuevo módulo: el módulo "msilib" permite crear archivos ".msi" y
  archivos CAB de Microsoft Installer. También se incluye cierta
  compatibilidad para leer la base de datos ".msi". (Contribución de
  Martin von Löwis).

* El módulo "nis" ahora permite acceder a dominios distintos del
  dominio predeterminado del sistema mediante el suministro de un
  argumento *domain* a las funciones "nis.match()" y "nis.maps()".
  (Contribuido por Ben Bell).

* The "operator" module's "itemgetter()"  and "attrgetter()" functions
  now support multiple fields.   A call such as
  "operator.attrgetter('a', 'b')" will return a function  that
  retrieves the "a" and "b" attributes.  Combining  this new feature
  with the "sort()" method's "key" parameter  lets you easily sort
  lists using multiple fields. (Contributed by Raymond Hettinger.)

* The "optparse" module was updated to version 1.5.1 of the Optik
  library. The "OptionParser" class gained an "epilog" attribute, a
  string that will be printed after the help message, and a
  "destroy()" method to break reference cycles created by the object.
  (Contributed by Greg Ward.)

* The "os" module underwent several changes.  The "stat_float_times"
  variable now defaults to true, meaning that "os.stat()" will now
  return time values as floats.  (This doesn't necessarily mean that
  "os.stat()" will return times that are precise to fractions of a
  second; not all systems support such precision.)

  Se han añadido las constantes "os.SEEK_SET", "os.SEEK_CUR" y
  "os.SEEK_END", que son los parámetros de la función "os.lseek()".
  Dos nuevas constantes para el bloqueo son "os.O_SHLOCK" y
  "os.O_EXLOCK".

  Two new functions, "wait3()" and "wait4()", were added.  They're
  similar the "waitpid()" function which waits for a child process to
  exit and returns a tuple of the process ID and its exit status, but
  "wait3()" and "wait4()" return additional information.  "wait3()"
  doesn't take a process ID as input, so it waits for any child
  process to exit and returns a 3-tuple of *process-id*, *exit-
  status*, *resource-usage* as returned from the
  "resource.getrusage()" function. "wait4(pid)" does take a process
  ID. (Contributed by Chad J. Schroeder.)

  On FreeBSD, the "os.stat()" function now returns  times with
  nanosecond resolution, and the returned object now has "st_gen" and
  "st_birthtime". The "st_flags" attribute is also available, if the
  platform supports it. (Contributed by Antti Louko and Diego
  Pettenò.)

* El depurador de Python proporcionado por el módulo "pdb" puede ahora
  almacenar listas de comandos a ejecutar cuando se alcanza un punto
  de ruptura y se detiene la ejecución.  Una vez creado el punto de
  interrupción nº 1, introduzca "comandos 1" e introduzca una serie de
  comandos a ejecutar, terminando la lista con "end".  La lista de
  comandos puede incluir comandos que reanuden la ejecución, como
  "continue" o "next". (Contribución de Grégoire Dooms.)

* Los módulos "pickle" y "cPickle" ya no aceptan un valor de retorno
  de "None" del método "__reduce__()"; en su lugar, el método debe
  devolver una tupla de argumentos. La capacidad de devolver "None"
  quedó obsoleta en Python 2.4, por lo que esto completa la
  eliminación de la función.

* El módulo "pkgutil", que contiene varias funciones de utilidad para
  encontrar paquetes, fue mejorado para soportar los ganchos de
  importación de **PEP 302** y ahora también funciona para paquetes
  almacenados en archivos con formato ZIP. (Contribución de Phillip J.
  Eby)

* El conjunto de pruebas pybench de Marc-André Lemburg se incluye
  ahora en el directorio "Tools/pybench".  El conjunto de pruebas
  pybench es una mejora del programa "pystone.py" de uso común, ya que
  pybench proporciona una medición más detallada de la velocidad del
  intérprete.  Calcula el tiempo de determinadas operaciones como las
  llamadas a funciones, el corte de tuplas, las búsquedas de métodos y
  las operaciones numéricas, en lugar de realizar muchas operaciones
  diferentes y reducir el resultado a un único número como hace
  "pystone.py".

* The "pyexpat" module now uses version 2.0 of the Expat parser.
  (Contributed by Trent Mick.)

* The "Queue" class provided by the "queue" module gained two new
  methods.  "join()" blocks until all items in the queue have been
  retrieved and all processing work on the items  have been completed.
  Worker threads call the other new method,  "task_done()", to signal
  that processing for an item has been completed.  (Contributed by
  Raymond Hettinger.)

* The old "regex" and "regsub" modules, which have been  deprecated
  ever since Python 2.0, have finally been deleted.   Other deleted
  modules: "statcache", "tzparse", "whrandom".

* Also deleted: the "lib-old" directory, which includes ancient
  modules such as "dircmp" and "ni", was removed.  "lib-old" wasn't on
  the default "sys.path", so unless your programs explicitly added the
  directory to "sys.path", this removal shouldn't affect your code.

* El módulo "rlcompleter" ya no depende de la importación del módulo
  "readline" y, por lo tanto, ahora funciona en plataformas no Unix.
  (Parche de Robert Kiendl.)

* The "SimpleXMLRPCServer" and "DocXMLRPCServer"  classes now have a
  "rpc_paths" attribute that constrains XML-RPC operations to a
  limited set of URL paths; the default is to allow only "'/'" and
  "'/RPC2'".  Setting "rpc_paths" to "None" or an empty tuple disables
  this path checking.

* The "socket" module now supports "AF_NETLINK" sockets on Linux,
  thanks to a patch from Philippe Biondi.   Netlink sockets are a
  Linux-specific mechanism for communications between a user-space
  process and kernel code; an introductory  article about them is at
  https://www.linuxjournal.com/article/7356. In Python code, netlink
  addresses are represented as a tuple of 2 integers, "(pid,
  group_mask)".

  Dos nuevos métodos en objetos socket, "recv_into(buffer)" y
  "recvrom_into(buffer)", almacenan los datos recibidos en un objeto
  que soporta el protocolo de buffer en lugar de devolver los datos
  como una cadena.  Esto significa que puedes poner los datos
  directamente en un array o en un archivo mapeado en memoria.

  Socket objects also gained "getfamily()", "gettype()", and
  "getproto()" accessor methods to retrieve the family, type, and
  protocol values for the socket.

* Nuevo módulo: el módulo "spwd" proporciona funciones para acceder a
  la base de datos de contraseñas ocultas en sistemas que admiten
  contraseñas ocultas.

* The "struct" is now faster because it  compiles format strings into
  "Struct" objects with "pack()" and "unpack()" methods.  This is
  similar to how the "re" module lets you create compiled regular
  expression objects.  You can still use the module-level  "pack()"
  and "unpack()" functions; they'll create  "Struct" objects and cache
  them.  Or you can use  "Struct" instances directly:

     s = struct.Struct('ih3s')

     data = s.pack(1972, 187, 'abc')
     year, number, name = s.unpack(data)

  También puedes empaquetar y desempaquetar datos hacia y desde
  objetos buffer directamente usando los métodos "pack_into(buffer,
  offset, v1, v2, ...)" y "unpack_from(buffer, offset)".  Esto te
  permite almacenar datos directamente en un array o en un archivo
  mapeado en memoria.

  ("Struct" objects were implemented by Bob Ippolito at the
  NeedForSpeed sprint.  Support for buffer objects was added by Martin
  Blais, also at the NeedForSpeed sprint.)

* Los desarrolladores de Python cambiaron de CVS a Subversion durante
  el proceso de desarrollo de la versión 2.5.  La información sobre la
  versión exacta de construcción está disponible como la variable
  "sys.subversion", una 3-tupla de "(nombre del intérprete, nombre de
  la rama, rango de revisión)".  Por ejemplo, en el momento de
  escribir esto, mi copia de 2.5 informaba de "('CPython', 'trunk',
  '45313:45315')".

  Esta información también está disponible para las extensiones de C a
  través de la función "Py_GetBuildInfo()" que devuelve una cadena de
  información de compilación como esta ""trunk:45355:45356M, Apr 13
  2006, 07:42:19"".   (Contribuido por Barry Warsaw.)

* Otra nueva función, "sys._current_frames()", devuelve los marcos de
  pila actuales para todos los hilos en ejecución como un diccionario
  que asigna los identificadores de los hilos al marco de pila
  superior actualmente activo en ese hilo en el momento en que se
  llama a la función.  (Contribuido por Tim Peters.)

* The "TarFile" class in the "tarfile" module now has an
  "extractall()" method that extracts all members from the archive
  into the current working directory.  It's also possible to set a
  different directory as the extraction target, and to unpack only a
  subset of the archive's members.

  La compresión utilizada para un archivo tar abierto en modo stream
  puede ahora ser autodetectada utilizando el modo "'r|*'".
  (Contribución de Lars Gustäbel)

* El módulo "threading" permite ahora establecer el tamaño de la pila
  utilizado cuando se crean nuevos hilos. La función
  "stack_size([*size*])" devuelve el tamaño de pila actualmente
  configurado, y suministrando el parámetro opcional *size* establece
  un nuevo valor.  No todas las plataformas soportan el cambio del
  tamaño de la pila, pero Windows, POSIX threading y OS/2 lo hacen.
  (Contribución de Andrew MacIntyre)

* El módulo "unicodedata" ha sido actualizado para utilizar la versión
  4.1.0 de la base de datos de caracteres Unicode.  La versión 3.2.0
  es requerida por algunas especificaciones, por lo que sigue estando
  disponible como "unicodedata.ucd_3_2_0".

* New module: the  "uuid" module generates  universally unique
  identifiers (UUIDs) according to **RFC 4122**.  The RFC defines
  several different UUID versions that are generated from a starting
  string, from system properties, or purely randomly.  This module
  contains a "UUID" class and  functions named "uuid1()", "uuid3()",
  "uuid4()",  and  "uuid5()" to generate different versions of UUID.
  (Version 2 UUIDs  are not specified in **RFC 4122** and are not
  supported by this module.)

     >>> import uuid
     >>> # make a UUID based on the host ID and current time
     >>> uuid.uuid1()
     UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

     >>> # make a UUID using an MD5 hash of a namespace UUID and a name
     >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
     UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')

     >>> # make a random UUID
     >>> uuid.uuid4()
     UUID('16fd2706-8baf-433b-82eb-8c7fada847da')

     >>> # make a UUID using a SHA-1 hash of a namespace UUID and a name
     >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
     UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')

  (Contribución de Ka-Ping Yee.)

* The "weakref" module's "WeakKeyDictionary" and "WeakValueDictionary"
  types gained new methods for iterating over the weak references
  contained in the dictionary.  "iterkeyrefs()" and "keyrefs()"
  methods were added to "WeakKeyDictionary", and "itervaluerefs()" and
  "valuerefs()" were added to "WeakValueDictionary".  (Contributed by
  Fred L. Drake, Jr.)

* The "webbrowser" module received a number of enhancements. It's now
  usable as a script with "python -m webbrowser", taking a URL as the
  argument; there are a number of switches  to control the behaviour
  ("-n" for a new browser window,  "-t" for a new tab).  New module-
  level functions, "open_new()" and "open_new_tab()", were added  to
  support this.  The module's "open()" function supports an additional
  feature, an *autoraise* parameter that signals whether to raise the
  open window when possible. A number of additional browsers were
  added to the supported list such as Firefox, Opera, Konqueror, and
  elinks.  (Contributed by Oleg Broytmann and Georg Brandl.)

* El módulo "xmlrpclib" ahora admite la devolución de objetos
  "datetime" para el tipo de fecha XML-RPC. Proporcione
  "use_datetime=True" a la función "loads()" o a la clase
  "Unmarshaller" para habilitar esta función. (Contribuido por Skip
  Montanaro).

* El módulo "zipfile" ahora soporta la versión ZIP64 del formato, lo
  que significa que un archivo .zip ahora puede ser mayor de 4 GiB y
  puede contener archivos individuales mayores de 4 GiB.
  (Contribución de Ronald Oussoren)

* The "zlib" module's "Compress" and "Decompress" objects now support
  a "copy()" method that makes a copy of the  object's internal state
  and returns a new  "Compress" or "Decompress" object. (Contributed
  by Chris AtLee.)


El paquete ctypes
-----------------

El paquete "ctypes", escrito por Thomas Heller, se ha añadido a la
biblioteca estándar. "ctypes" permite llamar a funciones arbitrarias
en bibliotecas compartidas o DLL. Los usuarios habituales pueden
recordar el módulo "dl", que proporciona funciones para cargar
bibliotecas compartidas y llamar a funciones en ellas. El paquete
"ctypes" es mucho más sofisticado.

To load a shared library or DLL, you must create an instance of the
"CDLL" class and provide the name or path of the shared library or
DLL. Once that's done, you can call arbitrary functions by accessing
them as attributes of the "CDLL" object.

   import ctypes

   libc = ctypes.CDLL('libc.so.6')
   result = libc.printf("Line of output\n")

Type constructors for the various C types are provided: "c_int()",
"c_float()", "c_double()", "c_char_p()" (equivalent to char*), and so
forth.  Unlike Python's types, the C versions are all mutable; you can
assign to their "value" attribute to change the wrapped value.  Python
integers and strings will be automatically converted to the
corresponding C types, but for other types you  must call the correct
type constructor.  (And I mean *must*;  getting it wrong will often
result in the interpreter crashing with a segmentation fault.)

You shouldn't use "c_char_p()" with a Python string when the C
function will be modifying the memory area, because Python strings are
supposed to be immutable; breaking this rule will cause puzzling bugs.
When you need a modifiable memory area, use "create_string_buffer()":

   s = "this is a string"
   buf = ctypes.create_string_buffer(s)
   libc.strfry(buf)

C functions are assumed to return integers, but you can set the
"restype" attribute of the function object to  change this:

   >>> libc.atof('2.71828')
   -1783957616
   >>> libc.atof.restype = ctypes.c_double
   >>> libc.atof('2.71828')
   2.71828

"ctypes" también proporciona un contenedor para la API C de Python
como el objeto "ctypes.pythonapi". Este objeto libera el bloqueo
global del intérprete antes de llamar a una función, porque el bloqueo
debe mantenerse al llamar al código del intérprete. Hay un constructor
de tipo "py_object" que creará un puntero PyObject*. Un uso simple:

   import ctypes

   d = {}
   ctypes.pythonapi.PyObject_SetItem(ctypes.py_object(d),
             ctypes.py_object("abc"),  ctypes.py_object(1))
   # d is now {'abc', 1}.

No olvide utilizar "py_object()"; si lo omite, terminará con un error
de segmentación.

"ctypes" existe desde hace tiempo, pero la gente sigue escribiendo y
distribuyendo módulos de extensión codificados a mano porque no se
puede confiar en que "ctypes" esté presente. Quizás los
desarrolladores empiecen a escribir envoltorios de Python sobre una
biblioteca a la que se accede a través de "ctypes" en lugar de módulos
de extensión, ahora que "ctypes" está incluido en el núcleo de Python.

Ver también:

  https://web.archive.org/web/20180410025338/http://starship.python.n
  et/crew/theller/ctypes/
     La página web pre-stdlib ctypes, con un tutorial, referencia y
     preguntas frecuentes.

  La documentación del módulo "ctypes".


El paquete ElementTree
----------------------

A subset of Fredrik Lundh's ElementTree library for processing XML has
been added to the standard library as "xml.etree".  The available
modules are "ElementTree", "ElementPath", and "ElementInclude" from
ElementTree 1.2.6.    The "cElementTree" accelerator module is also
included.

El resto de esta sección proporcionará una breve descripción general
del uso de ElementTree. La documentación completa de ElementTree está
disponible en
https://web.archive.org/web/20201124024954/http://effbot.org/zone
/element-index.htm.

ElementTree represents an XML document as a tree of element nodes. The
text content of the document is stored as the "text" and "tail"
attributes of  (This is one of the major differences between
ElementTree and the Document Object Model; in the DOM there are many
different types of node, including "TextNode".)

The most commonly used parsing function is "parse()", that takes
either a string (assumed to contain a filename) or a file-like object
and returns an "ElementTree" instance:

   from xml.etree import ElementTree as ET

   tree = ET.parse('ex-1.xml')

   feed = urllib.urlopen(
             'http://planet.python.org/rss10.xml')
   tree = ET.parse(feed)

Once you have an "ElementTree" instance, you can call its "getroot()"
method to get the root "Element" node.

There's also an "XML()" function that takes a string literal and
returns an "Element" node (not an "ElementTree").   This function
provides a tidy way to incorporate XML fragments, approaching the
convenience of an XML literal:

   svg = ET.XML("""<svg width="10px" version="1.0">
                </svg>""")
   svg.set('height', '320px')
   svg.append(elem1)

Cada elemento XML admite algunos métodos de acceso tipo diccionario y
otros tipo lista.  Las operaciones tipo diccionario se utilizan para
acceder a los valores de los atributos, y las operaciones tipo lista
se utilizan para acceder a los nodos hijos.

+---------------------------------+----------------------------------------------+
| Operación                       | Resultado                                    |
|=================================|==============================================|
| "elem[n]"                       | Devuelve el elemento hijo enésimo.           |
+---------------------------------+----------------------------------------------+
| "elem[m:n]"                     | Devuelve la lista de m's a n's elementos     |
|                                 | hijos.                                       |
+---------------------------------+----------------------------------------------+
| "len(elem)"                     | Devuelve el número de elementos hijos.       |
+---------------------------------+----------------------------------------------+
| "lista(elem)"                   | Devuelve la lista de elementos hijos.        |
+---------------------------------+----------------------------------------------+
| "elem.append(elem2)"            | Añade *elemento2* como hijo.                 |
+---------------------------------+----------------------------------------------+
| "elem.insert(index, elem2)"     | Inserta *elemento2* en el lugar              |
|                                 | especificado.                                |
+---------------------------------+----------------------------------------------+
| "del elem[n]"                   | Elimina el elemento hijo enésimo.            |
+---------------------------------+----------------------------------------------+
| "elem.keys()"                   | Devuelve la lista de nombres de atributos.   |
+---------------------------------+----------------------------------------------+
| "elem.get(name)"                | Devuelve el valor del atributo *nombre*.     |
+---------------------------------+----------------------------------------------+
| "elem.set(nombre, valor)"       | Establece el nuevo valor del atributo        |
|                                 | *nombre*.                                    |
+---------------------------------+----------------------------------------------+
| "elem.attrib"                   | Recupera el diccionario que contiene los     |
|                                 | atributos.                                   |
+---------------------------------+----------------------------------------------+
| "del elem.attrib[name]"         | Borra el atributo *nombre*.                  |
+---------------------------------+----------------------------------------------+

Comments and processing instructions are also represented as "Element"
nodes.  To check if a node is a comment or processing instructions:

   if elem.tag is ET.Comment:
       ...
   elif elem.tag is ET.ProcessingInstruction:
       ...

To generate XML output, you should call the
"xml.etree.ElementTree.ElementTree.write()" method. Like "parse()", it
can take either a string or a file-like object:

   # Encoding is US-ASCII
   tree.write('output.xml')

   # Encoding is UTF-8
   f = open('output.xml', 'w')
   tree.write(f, encoding='utf-8')

(Atención: la codificación por defecto utilizada para la salida es
ASCII.  Para el trabajo general de XML, donde el nombre de un elemento
puede contener caracteres Unicode arbitrarios, ASCII no es una
codificación muy útil porque lanzará una excepción si el nombre de un
elemento contiene cualquier carácter con valores superiores a 127.
Por lo tanto, es mejor especificar una codificación diferente, como
UTF-8, que puede manejar cualquier carácter Unicode)

Esta sección es sólo una descripción parcial de las interfaces de
ElementTree. Por favor, lee la documentación oficial del paquete para
más detalles.

Ver también:

  https://web.archive.org/web/20201124024954/http://effbot.org/zone
  /element-index.htm
     Documentación oficial de ElementTree.


El paquete hashlib
------------------

Se ha añadido un nuevo módulo "hashlib", escrito por Gregory P. Smith,
para sustituir a los módulos "md5" y "sha". "hashlib" añade
compatibilidad con hashes seguros adicionales (SHA-224, SHA-256,
SHA-384 y SHA-512). Cuando está disponible, el módulo utiliza OpenSSL
para implementaciones rápidas y optimizadas de algoritmos para
plataformas.

Los módulos antiguos "md5" y "sha" todavía existen como contenedores
de hashlib para preservar la compatibilidad con versiones anteriores.
La interfaz del nuevo módulo es muy similar a la de los módulos
antiguos, pero no idéntica. La diferencia más significativa es que las
funciones constructoras para crear nuevos objetos hash tienen nombres
diferentes.

   # Versiones anteriores
   h = md5.md5()
   h = md5.new()

   # Nueva versión
   h = hashlib.md5()

   # Versiones anteriores
   h = sha.sha()
   h = sha.new()

   # Nueva versión
   h = hashlib.sha1()

   # Hash que no estaban disponibles anteriormente
   h = hashlib.sha224()
   h = hashlib.sha256()
   h = hashlib.sha384()
   h = hashlib.sha512()

   # Forma alternativa
   h = hashlib.new('md5') # Proporcionar algoritmo como cadena

Once a hash object has been created, its methods are the same as
before: "update(string)" hashes the specified string into the  current
digest state, "digest()" and "hexdigest()" return the digest value as
a binary string or a string of hex digits, and "copy()" returns a new
hashing object with the same digest state.

Ver también: La documentación del módulo "hashlib".


El paquete sqlite3
------------------

El módulo pysqlite (https://www.pysqlite.org), un envoltorio para la
base de datos incrustada de SQLite, se agregó a la biblioteca estándar
con el nombre de paquete "sqlite3".

SQLite es una biblioteca en C que proporciona una base de datos ligera
basada en disco que no requiere un proceso de servidor independiente y
permite acceder a la base de datos utilizando una variante no estándar
del lenguaje de consulta SQL. Algunas aplicaciones pueden utilizar
SQLite para el almacenamiento interno de datos.  También es posible
crear un prototipo de una aplicación utilizando SQLite y luego portar
el código a una base de datos más grande como PostgreSQL u Oracle.

pysqlite fue escrito por Gerhard Häring y proporciona una interfaz SQL
que cumple con la especificación DB-API 2.0 descrita por **PEP 249**.

Si estás compilando el código fuente de Python tú mismo, ten en cuenta
que el árbol de código fuente no incluye el código de SQLite, sólo el
módulo envolvente. Necesitarás tener las librerías y cabeceras de
SQLite instaladas antes de compilar Python, y el proceso de
construcción compilará el módulo cuando las cabeceras necesarias estén
disponibles.

To use the module, you must first create a "Connection" object that
represents the database.  Here the data will be stored in the
"/tmp/example" file:

   conn = sqlite3.connect('/tmp/ejemplo')

También puede suministrar el nombre especial ":memory:" para crear una
base de datos en la RAM.

Once you have a "Connection", you can create a "Cursor"  object and
call its "execute()" method to perform SQL commands:

   c = conn.cursor()

   # Create table
   c.execute('''create table stocks
   (date text, trans text, symbol text,
    qty real, price real)''')

   # Insert a row of data
   c.execute("""insert into stocks
             values ('2006-01-05','BUY','RHAT',100,35.14)""")

Normalmente tus operaciones SQL necesitarán usar valores de variables
de Python.  No deberías montar tu consulta usando las operaciones de
cadena de Python porque hacerlo es inseguro; hace que tu programa sea
vulnerable a un ataque de inyección SQL.

Instead, use the DB-API's parameter substitution.  Put "?" as a
placeholder wherever you want to use a value, and then provide a tuple
of values as the second argument to the cursor's "execute()" method.
(Other database modules may use a different placeholder, such as "%s"
or ":1".) For example:

   # Never do this -- insecure!
   symbol = 'IBM'
   c.execute("... where symbol = '%s'" % symbol)

   # Do this instead
   t = (symbol,)
   c.execute('select * from stocks where symbol=?', t)

   # Larger example
   for t in (('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ):
       c.execute('insert into stocks values (?,?,?,?,?)', t)

To retrieve data after executing a SELECT statement, you can either
treat the cursor as an iterator, call the cursor's "fetchone()" method
to retrieve a single matching row,  or call "fetchall()" to get a list
of the matching rows.

Este ejemplo utiliza la forma del iterador:

   >>> c = conn.cursor()
   >>> c.execute('select * from stocks order by price')
   >>> for row in c:
   ...    print row
   ...
   (u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
   (u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
   (u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
   (u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
   >>>

Para más información sobre el dialecto SQL soportado por SQLite,
consulte https://www.sqlite.org.

Ver también:

  https://www.pysqlite.org
     La página web de pysqlite.

  https://www.sqlite.org
     La página web de SQLite; la documentación describe la sintaxis y
     los tipos de datos disponibles para el dialecto SQL soportado.

  La documentación del módulo "sqlite3".

  **PEP 249** - Especificación de la API de la base de datos 2.0
     PEP escrito por Marc-André Lemburg.


El paquete wsgiref
------------------

La Interfaz de Pasarela del Servidor Web (WSGI) v1.0 define una
interfaz estándar entre los servidores web y las aplicaciones web de
Python y se describe en **PEP 333**. El paquete "wsgiref" es una
implementación de referencia de la especificación WSGI.

El paquete incluye un servidor HTTP básico que ejecutará una
aplicación WSGI; este servidor es útil para la depuración pero no está
pensado para su uso en producción.  La configuración de un servidor
sólo requiere unas pocas líneas de código:

   from wsgiref import simple_server

   wsgi_app = ...

   host = ''
   port = 8000
   httpd = simple_server.make_server(host, port, wsgi_app)
   httpd.serve_forever()

Ver también:

  https://web.archive.org/web/20160331090247/http://wsgi.readthedocs.
  org/en/latest/
     Un sitio web central para los recursos relacionados con WSGI.

  **PEP 333** - Interfaz del servidor web Python v1.0
     PEP escrito por Phillip J. Eby.


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

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

* El árbol de fuentes de Python fue convertido de CVS a Subversion, en
  un complejo procedimiento de migración que fue supervisado y llevado
  a cabo de forma impecable por Martin von Löwis.  El procedimiento se
  desarrolló como **PEP 347**.

* Coverity, una empresa que comercializa una herramienta de análisis
  de código fuente llamada Prevent, proporcionó los resultados de su
  examen del código fuente de Python.  El análisis encontró alrededor
  de 60 errores que fueron rápidamente corregidos.  Muchos de los
  errores eran problemas de recuento, que a menudo se producen en el
  código de gestión de errores.  Consulte las estadísticas en
  https://scan.coverity.com.

* El mayor cambio en la API de C provino de **PEP 353**, que modifica
  el intérprete para usar una definición de tipo "Py_ssize_t" en lugar
  de int. Consulte la sección anterior PEP 353: Uso de ssize_t como
  tipo de índice para obtener una explicación de este cambio.

* El diseño del compilador de código de bytes ha cambiado mucho, ya no
  genera código de bytes recorriendo el árbol de análisis sintáctico.
  En su lugar, el árbol de análisis se convierte en un árbol de
  sintaxis abstracta (o AST), y es el árbol de sintaxis abstracta el
  que se recorre para producir el código de bytes.

  Es posible que el código Python obtenga objetos AST utilizando el
  built-in "compile()" y especificando "_ast.PyCF_ONLY_AST" como valor
  del parámetro *flags*:

     from _ast import PyCF_ONLY_AST
     ast = compile("""a=0
     for i in range(10):
         a += i
     """, "<string>", 'exec', PyCF_ONLY_AST)

     assignment = ast.body[0]
     for_loop = ast.body[1]

  No official documentation has been written for the AST code yet, but
  **PEP 339** discusses the design.  To start learning about the code,
  read the definition of the various AST nodes in
  "Parser/Python.asdl".  A Python script reads this file and generates
  a set of C structure definitions in "Include/Python-ast.h".  The
  "PyParser_ASTFromString()" and "PyParser_ASTFromFile()", defined in
  "Include/pythonrun.h", take Python source as input and return the
  root of an AST representing the contents. This AST can then be
  turned into a code object by "PyAST_Compile()".  For more
  information, read the source code, and then ask questions on python-
  dev.

  El código de la AST fue desarrollado bajo la dirección de Jeremy
  Hylton, e implementado por (en orden alfabético) Brett Cannon, Nick
  Coghlan, Grant Edwards, John Ehresman, Kurt Kaiser, Neal Norwitz,
  Tim Peters, Armin Rigo y Neil Schemenauer, además de los
  participantes en varios sprints de la AST en conferencias como la
  PyCon.

* Se aplicó el parche de Evan Jones a obmalloc, descrito por primera
  vez en una charla en la PyCon DC 2005.  Python 2.4 asignaba objetos
  pequeños en arenas de 256K, pero nunca liberaba arenas.  Con este
  parche, Python liberará arenas cuando estén vacías.  El efecto neto
  es que en algunas plataformas, cuando se asignan muchos objetos, el
  uso de la memoria de Python puede realmente caer cuando se borran y
  la memoria puede ser devuelta al sistema operativo.  (Implementado
  por Evan Jones, y reelaborado por Tim Peters)

  Tenga en cuenta que este cambio significa que los módulos de
  extensión deben ser más cuidadosos al asignar memoria.  La API de
  Python tiene muchas funciones diferentes para asignar memoria que se
  agrupan en familias.  Por ejemplo, "PyMem_Malloc()",
  "PyMem_Realloc()", y "PyMem_Free()" son una familia que asigna
  memoria en bruto, mientras que "PyObject_Malloc()",
  "PyObject_Realloc()", y "PyObject_Free()" son otra familia que se
  supone que se utiliza para crear objetos de Python.

  Anteriormente estas diferentes familias se reducían a las funciones
  "malloc()" y "free()" de la plataforma.  Esto significaba que no
  importaba si te equivocabas y asignabas memoria con la función
  "PyMem" pero la liberabas con la función "PyObject".  Con los
  cambios de la versión 2.5 en obmalloc, estas familias hacen ahora
  cosas diferentes y los desajustes probablemente darán lugar a un
  fallo de seguridad.  Deberías probar cuidadosamente tus módulos de
  extensión C con Python 2.5.

* Los tipos de conjuntos incorporados tienen ahora una API oficial en
  C.  Llame a "PySet_New()" y "PyFrozenSet_New()" para crear un nuevo
  conjunto, "PySet_Add()" y "PySet_Discard()" para añadir y eliminar
  elementos, y "PySet_Contains()" y "PySet_Size()" para examinar el
  estado del conjunto. (Contribución de Raymond Hettinger)

* El código C puede ahora obtener información sobre la revisión exacta
  del intérprete de Python llamando a la función "Py_GetBuildInfo()"
  que devuelve una cadena de información de compilación como esta
  ""trunk:45355:45356M, Apr 13 2006, 07:42:19"".   (Contribuido por
  Barry Warsaw.)

* Two new macros can be used to indicate C functions that are local to
  the current file so that a faster calling convention can be used.
  "Py_LOCAL" declares the function as returning a value of the
  specified *type* and uses a fast-calling qualifier.
  "Py_LOCAL_INLINE" does the same thing and also requests the function
  be inlined.  If macro "PY_LOCAL_AGGRESSIVE" is defined before
  "python.h" is included, a set of more aggressive optimizations are
  enabled for the module; you should benchmark the results to find out
  if these optimizations actually make the code faster.  (Contributed
  by Fredrik Lundh at the NeedForSpeed sprint.)

* "PyErr_NewException(name, base, dict)" ahora puede aceptar una tupla
  de clases base como su argumento *base*.  (Contribuido por Georg
  Brandl.)

* La función "PyErr_Warn()" para emitir avisos está ahora obsoleta en
  favor de "PyErr_WarnEx(category, message, stacklevel)" que permite
  especificar el número de marcos de pila que separan esta función y
  la que la llama.  Un *stacklevel* de 1 es la función que llama a
  "PyErr_WarnEx()", 2 es la función que está por encima, y así
  sucesivamente.  (Añadido por Neal Norwitz.)

* El intérprete de CPython sigue estando escrito en C, pero el código
  ahora puede ser compilado con un compilador de C++ sin errores.
  (Implementado por Anthony Baxter, Martin von Löwis, Skip Montanaro)

* Se ha eliminado la función "PyRange_New()".  Nunca se documentó,
  nunca se utilizó en el código del núcleo, y tenía una comprobación
  de errores peligrosamente laxa.  En el improbable caso de que sus
  extensiones la utilizaran, puede sustituirla por algo como lo
  siguiente:

     range = PyObject_CallFunction((PyObject*) &PyRange_Type, "lll",
                                   start, stop, step);


Cambios específicos en los puertos
----------------------------------

* MacOS X (10.3 y superior): la carga dinámica de módulos utiliza
  ahora la función "dlopen()" en lugar de funciones específicas de
  MacOS.

* MacOS X: se ha añadido una opción "--enable-universalsdk" al script
  **configure** que compila el intérprete como un binario universal
  capaz de funcionar tanto en procesadores PowerPC como Intel.
  (Contribución de Ronald Oussoren; bpo-2573.)

* Windows: ".dll" ya no se admite como extensión de nombre de archivo
  para los módulos de extensión. ".pyd" es ahora la única extensión de
  nombre de archivo que se buscará.


Adaptación a Python 2.5
=======================

Esta sección enumera los cambios descritos anteriormente que pueden
requerir cambios en su código:

* ASCII es ahora la codificación por defecto para los módulos.  Ahora
  es un error de sintaxis si un módulo contiene literales de cadena
  con caracteres de 8 bits pero no tiene una declaración de
  codificación.  En Python 2.4 esto provocaba una advertencia, no un
  error de sintaxis.

* Previously, the "gi_frame" attribute of a generator was always a
  frame object.  Because of the **PEP 342** changes described in
  section PEP 342: Nuevas funciones del generador, it's now possible
  for "gi_frame" to be "None".

* Una nueva advertencia, "UnicodeWarning", se lanza cuando se intenta
  comparar una cadena Unicode y una cadena de 8 bits que no puede ser
  convertida a Unicode utilizando la codificación ASCII por defecto.
  Anteriormente estas comparaciones lanzaban una excepción
  "UnicodeDecodeError".

* Biblioteca: el módulo "csv" es ahora más estricto con los campos
  citados en varias líneas. Si sus archivos contienen nuevas líneas
  incrustadas dentro de los campos, la entrada debe dividirse en
  líneas de manera que se conserven los caracteres de nueva línea.

* Biblioteca: la función "format()" del módulo "locale" aceptaba antes
  cualquier cadena siempre que no apareciera más de un especificador
  %char.  En Python 2.5, el argumento debe ser exactamente un
  especificador %char sin texto alrededor.

* Biblioteca: Los módulos "pickle" y "cPickle" ya no aceptan un valor
  de retorno de "None" del método "__reduce__()"; en su lugar, el
  método debe devolver una tupla de argumentos. Los módulos tampoco
  aceptan el parámetro de palabra clave *bin*, que ya no se utiliza.

* Library: The "SimpleXMLRPCServer" and "DocXMLRPCServer"  classes now
  have a "rpc_paths" attribute that constrains XML-RPC operations to a
  limited set of URL paths; the default is to allow only "'/'" and
  "'/RPC2'". Setting  "rpc_paths" to "None" or an empty tuple disables
  this path checking.

* API de C: muchas funciones ahora usan "Py_ssize_t" en lugar de int
  para permitir el procesamiento de más datos en máquinas de 64 bits.
  Es posible que el código de extensión deba realizar el mismo cambio
  para evitar advertencias y admitir máquinas de 64 bits. Consulte la
  sección anterior PEP 353: Uso de ssize_t como tipo de índice para
  obtener una explicación de este cambio.

* API C:  Los cambios en obmalloc significan que debe tener cuidado de
  no mezclar el uso de las familias de funciones "PyMem_*" y
  "PyObject_*". La memoria asignada con la función "*_Malloc" de una
  familia, debe ser liberada con la función "*_Free" de la familia
  correspondiente.


Agradecimientos
===============

El autor desea agradecer a las siguientes personas sus sugerencias,
correcciones y ayuda en varios borradores de este artículo: Georg
Brandl, Nick Coghlan, Phillip J. Eby, Lars Gustäbel, Raymond
Hettinger, Ralf W. Grosse-Kunstleve, Kent Johnson, Iain Lowe, Martin
von Löwis, Fredrik Lundh, Andrew McNamara, Skip Montanaro, Gustavo
Niemeyer, Paul Prescod, James Pryor, Mike Rovner, Scott Weikart, Barry
Warsaw, Thomas Wouters.
