Qué hay de nuevo en Python 2.4

Autor:

A.M. Kuchling

Este artículo explica las nuevas funcionalidades en Python 2.4.1 lanzadas el 30 de marzo de 2005.

Python 2.4 es un lanzamiento de término medio. Esto significa que no se han introducido grandes cambios como en la versión 2.2 de Python pero si son más significativas que la versión 2.3. Lo más relevante de estas nuevas funcionalidades son los decoradores y generadores de expresiones, la mayor parte del resto de los cambios son a la librería estándar.

De acuerdo al registro de cambios CVS , han sido aplicados 481 parches y 502 bugs han sido corregidos entre las versiones 2.3 y 2.4 de Python. Es posible que ambas cifras no concuerden con la realidad, podrían estar subestimadas.

Este artículo no pretende proveer una especificación completa y detallada de cada funcionalidad nueva, en vez de esto, se provee una breve descripción de las nuevas características. Para obtener más información se debe consultar la documentación oficial de Python 2.4, tal como la librería de referencia de Python y el manual de referencia de Python. Otra fuente de información es PEP (guía de estilo-mejoras de python) para buscar información sobre la implementación y fundamentación del diseño.

PEP 218: Objetos conjunto integrados

Python 2.3 introduced the sets module. C implementations of set data types have now been added to the Python core as two new built-in types, set(iterable) and frozenset(iterable). They provide high speed operations for membership testing, for eliminating duplicates from sequences, and for mathematical operations like unions, intersections, differences, and symmetric differences.

>>> a = set('abracadabra') # formar un conjunto a partir de una cadena
>>> 'z' en a # prueba rápida de pertenencia
Falso
>>> a # letras únicas en a
set(['a', 'r', 'b', 'c', 'd'])
>>> ''.join(a) # convertir de nuevo a una cadena
'arbcd'

>>> b = set('alacazam') # formar un segundo conjunto
>>> a - b # letras en a pero no en b
set(['r', 'd', 'b'])
>>> a | b # letras en a o b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b # letras en a y b
set(['a', 'c'])
>>> a ^ b # letras en a o b pero no en ambos
set(['r', 'd', 'b', 'm', 'z', 'l'])

>>> a.add('z') # agrega un nuevo elemento
>>> a.update('wxy') # agrega varios elementos nuevos
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'x', 'z'])
>>> a.remove('x') # saca un elemento
>>> a
set(['a', 'c', 'b', 'd', 'r', 'w', 'y', 'z'])

La función de conjuntos integrados frozenset() es una versión inmutable de set(). Como es inmutable y hashable (su valor no cambia), se puede usar como una llave de diccionario o como parte de otro set.

The sets module remains in the standard library, and may be useful if you wish to subclass the Set or ImmutableSet classes. There are currently no plans to deprecate the module.

Ver también

PEP 218 - Agregando tipo de objeto integrado set

Originalmente propuesto por Greg Wilson e implementado finalmente por Raymond Hettinger.

PEP 237: Unificando enteros largos y enteros

El prolongado proceso de transición para este PEP que comenzó en Python 2.2 ha dado un paso más adelante en Python 2.4. En la versión 2.3 ciertas operaciones de enteros podían comportarse diferente después de lanzar la unificación del tipo de dato int-long entregando alertas FutureWarning y retornando valores limitados a 32 o 64 bits dependiendo de su plataforma. En la versión 2.4 estas expresiones ya no producen alertas y en vez de eso entrega un resultado diferente que suele ser un entero largo.

Las expresiones problemáticas son principalmente desplazamientos a la izquierda y constantes largas de hexadecimales y octales. Por ejemplo, 2 << 32 entrega una alerta en la versión 2.3 y evalúa 0 en plataformas 32-bit. Ahora en Python 2.4 la expresión retorna la respuesta correcta, 8589934592.

Ver también

PEP 237 - Unificando enteros largos y enteros

PEP original escrito por Moshe Zadka y GvR. Los cambios a la versión 2.4 fueron implementados por Kalle Svensson.

PEP 289: Expresiones generadoras

La función de iterador introducida en Python 2.2 y el módulo itertools facilitan la escritura de programas que recorren grandes conjuntos de datos sin tener todo el conjunto de datos en la memoria al mismo tiempo. Las listas de comprensión no encajan muy bien en esta imagen porque producen un objeto de lista de Python que contiene todos los elementos. Esto inevitablemente lleva todos los objetos a la memoria, lo que puede ser un problema si su conjunto de datos es muy grande. Al tratar de escribir un programa de estilo funcional, sería natural escribir algo como:

links = [enlace para enlace en get_all_links() si no es link.followed]
para enlace en enlaces:
...

en vez de

para el enlace en get_all_links():
si link.followed:
continúa
...

La primera forma es mas concisa y quizás mas legible pero en caso de trabajar con un gran número largo de objetos podría ser necesario el escribir una segunda línea para evitar tener los objetos enlazados en memoria al mismo tiempo.

Las expresiones generadoras trabajan de forma similar a las listas por comprensión pero no materializan la lista completa, en vez de eso se crea un generador que retornará los elementos uno a uno. El siguiente ejemplo podría ser escrito como:

links = (enlace para enlace en get_all_links() si no se sigue el enlace)
para enlace en enlaces:
...

Los generadores de expresiones siempre tienen que ser escritos dentro de paréntesis como en el ejemplo descrito arriba. Los paréntesis señalan una llamada a la función que también se puede contar, entonces si se necesita crear un iterador que inmediatamente pasara a una función se podría escribir:

imprimir suma(obj.count para obj en list_all_objects())

Las expresiones generadoras difieren de las listas de comprensión por pequeñas diferencias. La mas notable es que la variable del loop (obj en el ejemplo de arriba) no es accesible fuera de la expresión generadora. Las listas de comprensión dejan la variable asignada a su último valor, en versiones futuras de Python esto será cambiado en lo que respecta a hacer que las listas de comprensión coincidan con las expresiones de los generadores.

Ver también

PEP 289 - Expresiones generadoras

Propuesto por Raymond Hettinger e implementada por Jiwon Seo con los primeros esfuerzos dirigidos por Hye-Shik Chang.

PEP 292: Sustituciones simples de cadenas de caracteres

Algunas nuevas clases en la librería estándar proveen un mecanismo alternativo para sustituir variables dentro de cadenas de caracteres, este estilo de sustituciones puede ser mejor por aplicaciones donde usuarios sin experiencia necesitan editar plantillas.

La manera usual de sustituir variables por el nombre es con el operador % :

>>> '%(page)i: %(title)s' % {'page':2, 'title': 'Lo mejor de los tiempos'}
'2: Lo mejor de los tiempos'

Cuando se escriben plantillas con cadenas de caracteres puede ser muy fácil olvidar el uso de i or s después de cerrar paréntesis. Esto no es un problema grande si se está dentro de un módulo de Python pues al correr el código se lanza el siguiente mensaje de error «Unsupported format character» ValueError y el problema se resuelve. Sin embargo, tengamos en cuenta una aplicación como Mailman donde una plantilla de caracteres o traducciones son editadas por usuarios que no están familiarizados con Python. La sintaxis de como formatear las cadenas de caracteres es complicada de explicar para ciertos usuarios y si ellos cometen un error es una dificultad el entregar retroalimentación y ayuda.

PEP 292 adds a Template class to the string module that uses $ to indicate a substitution:

>>> import string
>>> t = string.Template('$page: $title')
>>> t.substitute({'page':2, 'title': 'Lo mejor de los tiempos'})
'2: Lo mejor de los tiempos'

If a key is missing from the dictionary, the substitute() method will raise a KeyError. There’s also a safe_substitute() method that ignores missing keys:

>>> t = string.Template('$página: $título')
>>> t.safe_substitute({'página':3})
'3: $título'

Ver también

PEP 292 - Sustituciones simples de cadenas de caracteres

Escrito e implementado por Barry Warsaw.

PEP 318: Decoradores para funciones y métodos

Python 2.2 extendió el modelo de objeto de Python añadiendo métodos estáticos y métodos de clase pero no se extendió la sintaxis de Python para proveer alguna nueva forma de definir métodos estáticos o de clase. En vez de eso se tenía que escribir la palabra clave def de manera usual y pasar el método resultante a la staticmethod() o a la classmethod() que podía agrupar la función como método de un nuevo tipo. El código podría verse como esto:

clase C:
def meth (cls):
...

meth = classmethod(meth) # Volver a vincular el nombre al método de clase encapsulado

Si el método era muy largo, era muy probable el perder o olvidar la invocación classmethod() dentro del cuerpo de la función.

La intención era siempre agregar alguna sintaxis que hicieran las definiciones mas entendibles pero al tiempo del lanzamiento de la versión 2.2 una buena sintaxis no era clara. Al día de hoy una buena sintaxis aun no es clara pero los usuarios están preguntando por formas más fáciles de acceder a las características, entonces una nueva funcionalidad sintáctica ha sido añadida para satisfacer esta necesidad.

La nueva característica es llamada decoradores de funciones. El nombre proviene de la idea de que classmethod(), staticmethod() son amigos y guardan información adicional en un objeto de una función. ellos están decorando funciones con mas detalles.

La notación proviene de Java y usa el '@' símbolo arroba como un indicador. Usando la nueva sintaxis el ejemplo descrito arriba podría ser escrito de la siguiente forma:

clase C:

@classmethod
def meth (cls):
...

El @classmethod es un atajo para meth=classmethod(meth). De forma general si se tiene lo siguiente:

@A
@B
@C
def f():
...

Es el equivalente para el siguiente código de pre decorador:

definición f(): ...
f = A(B(C(f)))

Los decoradores deben agregarse en una línea antes de la definición de la función, un decorador por línea y no puede estar en la misma línea donde se usa la palabra def para comenzar una función, por ejemplo @A def f(): ... es incorrecto. Solo se puede decorar una definición de función tanto al nivel de módulo o dentro de una clase pero no puedes decorar definiciones de clase.

Un decorador es simplemente una función que toma la función a ser decorada como un argumento y retorna tanto la misma función o un nuevo objeto. El valor de retorno del decorador no necesita ser llamado (como típicamente se cree) si no que los decoradores podrán ser aplicados al resultado. Es fácil escribir sus propios decoradores. El siguiente ejemplo agrega un atributo a la función objetiva:

>>> def deco(func):
... func.attr = 'decorado'
... return func
...
>>> @deco
... def f(): pass
...
>>> f
<función f en 0x402ef0d4>
>>> f.attr
'decorado'
>>>

Como un ejemplo un poco mas realista, el siguiente decorador revisa si el argumento entregado es un entero:

def require_int (función):
def contenedor (arg):
assert isinstance(arg, int)
return func(arg)

return contenedor

@require_int
def p1 (arg):
print arg

@require_int
def p2(arg):
print arg*2

Un ejemplo en PEP 318 contiene una versión mas elegante de esta idea donde deja que usted elija específicamente el tipo y revisa el tipo de retorno.

Los decoradores de funciones pueden tomar argumentos. Si los argumentos son provistos, el decorador de la función es llamado con solo esos argumentos y retorna un nuevo decorador de función, esta función debe tomar una función sola y retorna una función como previamente se ha descrito. En otras palabras @A @B @C(args) comienza:

def f(): ...
_deco = C(argumentos)
f = A(B(_deco(f)))

Conseguir que esto resulte correcto puede ser un acertijo pero tampoco es muy dificultoso.

Un pequeño cambio relacionado hace que el atributo func_name de las funciones sea escribible. Este atributo se utiliza para mostrar los nombres de las funciones en los seguimientos, por lo que los decoradores deben cambiar el nombre de cualquier función nueva que se construya y devuelva.

Ver también

PEP 318 Decoradores para funciones, métodos y clases

Escrito por Kevin D.Smith, Jim Jewett y Skip Montanaro. Varias personas escribieron parches sobre la implementación de los decoradores de funciones, pero el único que fue chequeado fue #979728 por Mark Russell.

https://wiki.python.org/moin/PythonDecoratorLibrary

Esta pagina de wiki contiene múltiples ejemplos de decoradores.

PEP 322: Iteración inversa

Una nueva función de conjuntos integrados, reversed(seq) toma una secuencia y retorna un iterador que recorre los elementos de la secuencia en orden inverso.:

>>> para i en reversed(xrange(1,4)):
... imprimir i
...
3
2
1

Comparado con el uso tradicional de la segmentación tal como range(1,4)[::-1] la función reversed() es fácil de leer, se ejecuta mas rápido y usa sustancialmente menos memoria.

Señalar que la función reversed() solo acepta secuencias, no iteradores arbitrarios. Si se quiere revertir un iterador, primero se debe convertir a una lista usando la función list().:

>>> input = open('/etc/passwd', 'r')
>>> for line in reversed(list(input)):
... print line
...
root:*:0:0:Administrador del sistema:/var/root:/bin/tcsh
...

Ver también

PEP 322 - Iteración inversa

Escrita e implementada por Raymond Hettinger.

PEP 324: Nuevo módulo de subproceso

La biblioteca estándar proporciona varias formas de ejecutar un subproceso, ofreciendo distintas funciones y distintos niveles de complejidad. os.system(command) es fácil de usar, pero lento (ejecuta un proceso de shell que ejecuta el comando) y peligroso (hay que tener cuidado con el escape de los metacaracteres del shell). El módulo popen2 ofrece clases que pueden capturar la salida estándar y el error estándar del subproceso, pero la nomenclatura es confusa. El módulo subprocess soluciona este problema, proporcionando una interfaz unificada que ofrece todas las funciones que se pueden necesitar.

En vez de popen2 que es una colección de clases el subprocess contiene una sola clase llamada subprocess.Popen cuyo constructor soporta un número de diferentes argumentos de palabra clave:

clase Popen(args, bufsize=0, ejecutable=Ninguno,
stdin=Ninguno, stdout=Ninguno, stderr=Ninguno,
preexec_fn=Ninguno, close_fds=False, shell=False,
cwd=Ninguno, env=Ninguno, universal_newlines=False,
startupinfo=Ninguno, creationflags=0):

args es comúnmente una secuencia de cadenas de caracteres que podrán ser los argumentos del programa ejecutado como un subproceso. (Si el argumento shell es verdadero, args puede ser una cadena de caracteres que serán pasados directamente a la shell para su interpretación, tal como os.system() lo hace.)

stdin, stdout, y stderr especifican que flujos de entrada, salida y error serán utilizados. Se puede proceder un objeto de archivo o un archivo de descripción o se puede usar la constante subprocess.PIPE para crear un enlace entre el subproceso y el proceso principal.

El constructor tiene un número de opciones útiles:

  • close_fds requiere que todos los descriptores de archivos sean cerrados antes de correr el subproceso.

  • cwd especifica el directorio operativo donde el subproceso será ejecutado (por defecto, cualquiera que sea el directorio principal)

  • env es un diccionario donde se especifican las variables de entorno.

  • preexec_fn es una función que es llamada antes de que el proceso hijo sea llamado.

  • universal_newlines abre el flujo de entrada y salida del hijo usando la característica de Python universal newlines .

Once you’ve created the Popen instance, you can call its wait() method to pause until the subprocess has exited, poll() to check if it’s exited without pausing, or communicate(data) to send the string data to the subprocess’s standard input. communicate(data) then reads any data that the subprocess has sent to its standard output or standard error, returning a tuple (stdout_data, stderr_data).

call() is a shortcut that passes its arguments along to the Popen constructor, waits for the command to complete, and returns the status code of the subprocess. It can serve as a safer analog to os.system():

sts = subprocess.call(['dpkg', '-i', '/tmp/new-package.deb'])
if sts == 0:
# Éxito
...
else:
# dpkg devolvió un error
...

El comando es invocado sin el uso del interprete de comandos. Si se desea usar el intérprete se puede agregar shell=True como un argumento de palabra clave y proveer una cadena de caracteres en vez de una secuencia:

sts = subproceso.call('dpkg -i /tmp/nuevo-paquete.deb', shell=True)

La guía de estilo de Python toma varios ejemplos de línea de comandos y código python y muestra como estos son traducidos en el código python subprocess. Leer esta sección de la guía de estilo es altamente recomendado.

Ver también

PEP 324 - subprocess - Nuevo módulo de procesos

Escrito e implementado por Peter Åstrand, con asistencia de Frederik Lundh y otros.

PEP 327: Tipo de dato decimal

Python has always supported floating-point (FP) numbers, based on the underlying C double type, as a data type. However, while most programming languages provide a floating-point type, many people (even programmers) are unaware that floating-point numbers don’t represent certain decimal fractions accurately. The new Decimal type can represent these fractions accurately, up to a user-specified precision limit.

¿Por qué se necesita Decimal?

Las limitaciones surgen de la representación usada para los números de punto flotante. Los números de punto flotante están hechos de tres componentes:

  • El signo, el cual es positivo o negativo.

  • El significando o mantisa el cual es el un dígito binario seguido de su parte fraccional. Por ejemplo, 1.01 en notación base 2 es 1 + 0/2 + 1/4 o 1.25 en notación decimal.

  • El exponente, que indica dónde se encuentra el punto decimal en el número representado.

Por ejemplo, el número 1.25 tiene un signo positivo, una mantisa de valor 1.01 (en binario) y un exponente de 0 (el punto decimal no necesita ser desplazado. El números 5 tiene el mismo signo y significando pero, el exponente es 2 porque el significando es multiplicado por 4 (2 elevado a la potencia del exponente 2), 1.25 * 4 es igual a 5.

Los sistemas modernos generalmente brindan soporte de coma flotante que se ajusta a un estándar llamado IEEE 754. El tipo double de C generalmente se implementa como un número IEEE 754 de 64 bits, que usa 52 bits de espacio para la mantisa. Esto significa que los números solo se pueden especificar con 52 bits de precisión. Si está tratando de representar números cuya expansión se repite sin cesar, la expansión se corta después de 52 bits. Desafortunadamente, la mayoría del software necesita producir resultados en base 10, y las fracciones comunes en base 10 a menudo son decimales repetidos en binario. Por ejemplo, 1.1 decimal es binario 1.0001100110011 ...; .1 = 1/16 + 1/32 + 1/256 más un número infinito de términos adicionales. IEEE 754 tiene que cortar ese decimal repetido infinitamente después de 52 dígitos, por lo que la representación es un poco inexacta.

Algunas veces se puede ver esta inexactitud cuando el número es impreso por pantalla:

>>> 1.1
1.1000000000000001

La inexactitud no siempre es visible cuando se imprime el número porque el punto flotante a decimal y conversión a cadena de texto es entregada por la librería C y la mayoría de las librerías C tratan de producir una salida sensible. Incluso si no es mostrado, la inexactitud sigue ahí y las operaciones subsecuentes pueden agrandar el error.

Para muchas aplicaciones esto no importa. Si estoy trazando puntos y mostrándolos en el monitor la diferencia entre 1.1 y 1.1000000000000001 es muy pequeña para ser visible. Los reportes a menudo limitan la salida de un cierto número de decimales y si se redondea el número a dos o tres e incluso a 8 decimales, el error nunca aparece. Sin embargo, para las aplicaciones donde esto importa, es una cantidad de trabajo importante el personalizar los cálculos aritméticos.

Hence, the Decimal type was created.

The Decimal type

A new module, decimal, was added to Python’s standard library. It contains two classes, Decimal and Context. Decimal instances represent numbers, and Context instances are used to wrap up various settings such as the precision and default rounding mode.

Decimal instances are immutable, like regular Python integers and FP numbers; once it’s been created, you can’t change the value an instance represents. Decimal instances can be created from integers or strings:

>>> importar decimal
>>> decimal.Decimal(1972)
Decimal("1972")
>>> decimal.Decimal("1.1")
Decimal("1.1")

También se pueden proveer tuplas que contentan el signo, la mantisa representada como una tupla de números decimales y el exponente:

>>> decimal.Decimal((1, (1, 4, 7, 5), -2))
Decimal("-14,75")

Precaución: El signo bit es un valor booleano entonces 0 es positivo y 1 es negativo.

Converting from floating-point numbers poses a bit of a problem: should the FP number representing 1.1 turn into the decimal number for exactly 1.1, or for 1.1 plus whatever inaccuracies are introduced? The decision was to dodge the issue and leave such a conversion out of the API. Instead, you should convert the floating-point number into a string using the desired precision and pass the string to the Decimal constructor:

>>> f = 1,1
>>> decimal.Decimal(str(f))
Decimal("1,1")
>>> decimal.Decimal('%.12f' % f)
Decimal("1,100000000000")

Once you have Decimal instances, you can perform the usual mathematical operations on them. One limitation: exponentiation requires an integer exponent:

>>> a = decimal.Decimal('35,72')
>>> b = decimal.Decimal('1,73')
>>> a+b
Decimal("37,45")
>>> a-b
Decimal("33,99")
>>> a*b
Decimal("61.7956")
>>> a/b
Decimal("20.64739884393063583815028902")
>>> a XASDF00b
Traceback (most recent call last):
  ...
decimal.InvalidOperation: x ** (no entero)

You can combine Decimal instances with integers, but not with floating-point numbers:

>>> a + 4
Decimal("39.72")
>>> a + 4.5
Traceback (última llamada más reciente):
...
TypeError: Solo puede interactuar con Decimal con tipos de datos int, long o Decimal.
>>>

Decimal numbers can be used with the math and cmath modules, but note that they’ll be immediately converted to floating-point numbers before the operation is performed, resulting in a possible loss of precision and accuracy. You’ll also get back a regular floating-point number and not a Decimal.

>>> importar matemáticas, cmath
>>> d = decimal.Decimal('123456789012.345')
>>> matemáticas.sqrt(d)
351364.18288201344
>>> cmath.sqrt(-d)
351364.18288201344j

Decimal instances have a sqrt() method that returns a Decimal, but if you need other things such as trigonometric functions you’ll have to implement them.

>>> d.sqrt()
Decimal("351364.1828820134592177245001")

The Context type

Instances of the Context class encapsulate several settings for decimal operations:

  • prec is the precision, the number of decimal places.

  • rounding specifies the rounding mode. The decimal module has constants for the various possibilities: ROUND_DOWN, ROUND_CEILING, ROUND_HALF_EVEN, and various others.

  • traps is a dictionary specifying what happens on encountering certain error conditions: either an exception is raised or a value is returned. Some examples of error conditions are division by zero, loss of precision, and overflow.

There’s a thread-local default context available by calling getcontext(); you can change the properties of this context to alter the default precision, rounding, or trap handling. The following example shows the effect of changing the precision of the default context:

>>> decimal.getcontext().prec
28
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0,1428571428571428571428571429")
>>> decimal.getcontext().prec = 9
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal("0,142857143")

Las acciones por defecto para condiciones de error se puede seleccionar, ya sea que el módulo pueda retornar un valor especial como un infinito o un valor no numérico NaN o se pueden lanzar excepciones:

>>> decimal.Decimal(1) / decimal.Decimal(0)
Traceback (última llamada más reciente):
...
decimal.DivisionByZero: x / 0
>>> decimal.getcontext().traps[decimal.DivisionByZero] = False
>>> decimal.Decimal(1) / decimal.Decimal(0)
Decimal("Infinito")
>>>

The Context instance also has various methods for formatting numbers such as to_eng_string() and to_sci_string().

Para mas información, revisar la documentación para el módulo decimal el cual incluye un tutoría de inicio rápido y una referencia.

Ver también

PEP 327 - Tipo de dato decimal

Escrito por Facundo Batista e implementado por Facundo Batista, Eric Price, Raymond Hettinger, Aahz y Tim Peters.

http://www.lahey.com/float.htm

El articulo usa código Fortran para ilustrar varios de los problemas que la inexactitud de los puntos flotantes pueden causar.

https://speleotrove.com/decimal/

Una descripción de una representación basada en decimales. Esta representación ha sido propuesta como un estándar y subyace al nuevo tipo de dato decimal en Python. La mayor parte de este material fue escrita por Mike Cowlishaw, diseñador del lenguaje Rexx.

PEP 328: Importaciones multilínea

Un pequeño cambio en el lenguaje ha sido una modificación a una sintaxis confusa que ha sido cambiada para hacer mas fácil el agregar varios nombres en un módulo. En una declaración from module import names, names es una secuencia de nombres separados por comas. Si la sentencia es muy larga, se puede ya sea escribir múltiples sentencias import desde el mismo módulo o se pueden usar barras invertidas para escapar de los términos de línea como esto:

de SimpleXMLRPCServer importar SimpleXMLRPCServer,\
SimpleXMLRPCRequestHandler,\
CGIXMLRPCRequestHandler,\
resolve_dotted_attribute

La sintaxis cambió en Python 2.4 y es simplemente el permitir poner los nombres dentro de paréntesis. Python ignora nuevas líneas dentro de una expresión entre paréntesis por lo que las barras invertidas ya no se necesitan:

from SimpleXMLRPCServer import (SimpleXMLRPCServer,
                                SimpleXMLRPCRequestHandler,
                                CGIXMLRPCRequestHandler,
                                resolve_dotted_attribute)

La convención de estilo también propone que todas las declaraciones usando import son importaciones absolutas, con el siguiente carácter . indica una importación relativa. Esta parte de la convención de estilo no fue implementada para Python 2.4 pero fue completada para la versión 2.5.

Ver también

PEP 328 - Importaciones multi línea y absolutas/relativas

Escrita por Aahz. Importaciones multi línea fueron implementadas por Dima Dorfman.

PEP 331: Conversiones locales-independientes números flotantes/cadenas de texto

The locale modules lets Python software select various conversions and display conventions that are localized to a particular country or language. However, the module was careful to not change the numeric locale because various functions in Python’s implementation required that the numeric locale remain set to the 'C' locale. Often this was because the code was using the C library’s atof() function.

No configurar la configuración regional numérica causaba problemas para las extensiones que usaban librerías externas de C, sin embargo, porque no configuraban la correcta configuración. El ejemplo mas patente fue GTK+, cuya interfaz de usuario no mostraba números en la ubicación actual.

La solución descrita en la convención de estilo es añadir tres nuevas funciones a la API de python que ejecuta solo conversiones a ASCII, ignorando las configuraciones locales:

  • PyOS_ascii_strtod(str, ptr) y PyOS_ascii_atof(str, ptr) convierten una cadena en C double.

  • PyOS_ascii_formatd(buffer, buf_len, format, d) convierte un double en una cadena ASCII.

El código para estas funciones proviene de la biblioteca GLib (https://developer-old.gnome.org/glib/2.26/), cuyos desarrolladores amablemente renovaron la licencia de las funciones relevantes y las donaron a la Python Software Foundation. El módulo locale ahora puede cambiar la configuración regional numérica, lo que permite que extensiones como GTK+ produzcan los resultados correctos.

Ver también

PEP 331 Conversiones Local-Independiente flotante/cadena de texto

Escrito por Christian R. Reis, e implementado por Gustavo Carneiro.

Otros cambios en el lenguaje

Aquí están todos los cambios que Python 2.4 ha hecho al core del lenguaje Python.

  • Fueron añadidos decoraciones para funciones (PEP 318).

  • Funciones de conjuntos integrados set() y frozenset() fueron añadidas (PEP 218). Otras nuevas funciones de conjuntos integrados incluyen la función reversed(seq) (PEP 322).

  • Generador de expresiones fueron añadidas (PEP 289).

  • Algunas expresiones numéricas ya no retornan valores restringidos a 32 o 64 bits (PEP 237).

  • Se puede poner entre paréntesis una lista de nombres en la declaración from module import names (PEP 328).

  • El método dict.update() ahora acepta el mismo argumento que el constructor de la dict. Esto incluye cualquier tipo de mapeo, iterable pares de clave/valor y argumentos de palabra clave. (Contribución de Raymond Hettinger)

  • The string methods ljust(), rjust(), and center() now take an optional argument for specifying a fill character other than a space. (Contributed by Raymond Hettinger.)

  • Strings also gained an rsplit() method that works like the split() method but splits from the end of the string. (Contributed by Sean Reifschneider.)

    >>> 'www.python.org'.split('.', 1)
    ['www', 'python.org']
    'www.python.org'.rsplit('.', 1)
    ['www.python', 'org']
    
  • Three keyword parameters, cmp, key, and reverse, were added to the sort() method of lists. These parameters make some common usages of sort() simpler. All of these parameters are optional.

    For the cmp parameter, the value should be a comparison function that takes two parameters and returns -1, 0, or +1 depending on how the parameters compare. This function will then be used to sort the list. Previously this was the only parameter that could be provided to sort().

    key debe ser una función con un solo parámetro que toma un elemento de la lista y retorna una llave de comparación para el elemento. Entonces la lista es ordenado usando las claves de comparación. El siguiente ejemplo ordena una lista sin distinción de mayúsculas ni minúsculas:

    >>> L = ['A', 'b', 'c', 'D']
    >>> L.sort() # Ordenación que distingue entre mayúsculas y minúsculas
    >>> L
    ['A', 'D', 'b', 'c']
    >>> # Uso del parámetro 'key' para ordenar la lista
    >>> L.sort(key=lambda x: x.lower())
    >>> L
    ['A', 'b', 'c', 'D']
    >>> # Método tradicional
    >>> L.sort(cmp=lambda x,y: cmp(x.lower(), y.lower()))
    >>> L
    ['A', 'b', 'c', 'D']
    

    The last example, which uses the cmp parameter, is the old way to perform a case-insensitive sort. It works but is slower than using a key parameter. Using key calls lower() method once for each element in the list while using cmp will call it twice for each comparison, so using key saves on invocations of the lower() method.

    Para funciones de clave sencillas y comparativas es a menudo posible el obviar la palabra clave lambda usando un método sin ligar en reemplazo. El siguiente ejemplo de orden sin importar mayúsculas ni minúsculas es mejor escrito como se muestra:

    >>> L.sort(key=str.lower)
    >>> L
    ['A', 'b', 'c', 'D']
    

    Finalmente el parámetro reverse toma un valor de tipo booleano. Si el valor es verdadero la lista será ordenada de forma inversa. En vez de L.sort(); L.reverse() ahora se puede escribir L.sort(reverse=True).

    Los resultados del ordenamiento ahora están garantizados que son estables. Esto significa que dos entradas con iguales claves serán retiradas en el mismo orden en que fueron ingresadas. Por ejemplo se puede ordenar una lista de personas por el nombre y entonces ordenarla por edad, resultando en una lista ordenada donde las personas con la misma edad están en el mismo orden por nombre.

    (All changes to sort() contributed by Raymond Hettinger.)

  • Se tiene una nueva función incorporada sorted(iterable) que trabaja como el método in situ list.sort() que se puede usar en expresiones. Las diferencias son:

  • el dato de entrada puede ser algún iterable;

  • se ordena una copia recién formada, manteniendo el original intacto y

  • la expresión retorna una nueva copia ordenada

    >>> L = [9,7,8,3,2,4,1,6,5]
    >>> [10+i for i in sorted(L)] # utilizable en una comprensión de lista
    [11, 12, 13, 14, 15, 16, 17, 18, 19]
    >>> L # el original no se modifica
    [9,7,8,3,2,4,1,6,5]
    >>> sorted('Monty Python') # cualquier iterable puede ser una entrada
    [' ', 'M', 'P', 'h', 'n', 'n', 'o', 'o', 't', 't', 'y', 'y']
    
    >>> # Lista el contenido de un diccionario ordenado por valores clave
    >>> colormap = dict(red=1, blue=2, green=3, black=4, yellow=5)
    >>> for k, v en sorted(colormap.iteritems()):
    ... imprimir k, v
    ...
    negro 4
    azul 2
    verde 3
    rojo 1
    amarillo 5
    

    (Contribución de Raymond Hettinger.)

  • Integer operations will no longer trigger an OverflowWarning. The OverflowWarning warning will disappear in Python 2.5.

  • Se añadió al interprete una nueva opción de cambio -m la cual toma un nombre, busca el módulo correspondiente en sys.path y corre el módulo como script. Ahora por ejemplo se puede correr el perfilador de Python con python -m profile. (Contribución de Nick Coghlan)

  • La expresión eval(expr, globals, locals) la función execfile(filename, globals, locals) y la sentencia exec ahora aceptan cualquier tipo de mapeo para parámetros locales. Previamente esto era parte de un diccionario de Python. (Contribución de Raymond Hettinger.)

  • The zip() built-in function and itertools.izip() now return an empty list if called with no arguments. Previously they raised a TypeError exception. This makes them more suitable for use with variable length argument lists:

    >>> def transpose(matriz):
    ... return zip(*matriz)
    ...
    >>> transpose([(1,2,3), (4,5,6)])
    [(1, 4), (2, 5), (3, 6)]
    >>> transpose([])
    []
    

    (Contribución de Raymond Hettinger.)

  • Encontrar un error al importar un módulo ya no deja un objeto de módulo parcialmente inicializado en sys.modules. El objeto de módulo incompleto que se deja atrás engañaría a las importaciones posteriores del mismo módulo para que tuvieran éxito, lo que generaría errores confusos. (Reparado por Tim Peters.)

  • None`es ahora una constante, el código que une un nuevo valor con el nombre :const:`None es ahora un error de sintaxis (Contribución de Raymond Hettinger)

Optimizaciones

  • The inner loops for list and tuple slicing were optimized and now run about one-third faster. The inner loops for dictionaries were also optimized, resulting in performance boosts for keys(), values(), items(), iterkeys(), itervalues(), and iteritems(). (Contributed by Raymond Hettinger.)

  • El mecanismo para mejorar y contraer listas fue optimizada para efectos de velocidad y eficiencia en la utilización de recursos. Anexar y quitar elementos de una lista es ahora mas rápido debido al código mas eficiente y al menos frecuente uso de la función subyacente realloc(). Las listas por comprensión también son beneficiadas, el método list.extend() fue también optimizado y ya no convierte mas el argumento en una lista temporal antes de extender la lista base. (Contribución de Raymond Hettinger)

  • list(), tuple(), map(), filter(), and zip() now run several times faster with non-sequence arguments that supply a __len__() method. (Contributed by Raymond Hettinger.)

  • The methods list.__getitem__(), dict.__getitem__(), and dict.__contains__() are now implemented as method_descriptor objects rather than wrapper_descriptor objects. This form of access doubles their performance and makes them more suitable for use as arguments to functionals: map(mydict.__getitem__, keylist). (Contributed by Raymond Hettinger.)

  • Adicionalmente se ha agregado a un nuevo código de operación LIST_APPEND esto simplifica la generación de código a nivel de byte para las listas por comprensión y las agiliza en aproximadamente un tercio.

  • El optimizador de código a nivel de byte ha sido mejorado para producir código a nivel de byte mas corto y rápido. Esto resulta en código mas legible. (Contribución de Raymond Hettinger)

  • String concatenations in statements of the form s = s + "abc" and s += "abc" are now performed more efficiently in certain circumstances. This optimization won’t be present in other Python implementations such as Jython, so you shouldn’t rely on it; using the join() method of strings is still recommended when you want to efficiently glue a large number of strings together. (Contributed by Armin Rigo.)

El resultado de las optimizaciones de la versión 2.4 es que tomando Python 2.4 como punto de referencia corre alrededor de un 5% mas rápido que Python 2.3 y un 35% mas rápido que Python 2.2 (pystone no es particularmente un buen punto de referencia pero es el mas usado para medir rendimiento en Python. Sus propias aplicaciones pueden mostrar beneficios mas grandes o mínimos desde Python 2.4)

Módulos nuevos, mejorados y obsoletos

Como es usual, la librería estándar de Python recibió un número de mejoras y corrección de errores. Aquí hay una lista parcial de los cambios mas notables, ordenados alfabéticamente por nombre de módulo. Consulte el archivo Misc/NEWS en la estructura del directorio para una completa lista de los cambios o se puede buscar a través del registro CVS para obtener todos los detalles.

  • La función loop() del módulo asyncore ahora tiene un parámetro count que le permite realizar una cantidad limitada de pasadas a través del bucle de sondeo. El valor predeterminado sigue siendo el bucle indefinidamente.

  • El módulo base64 ahora tiene un soporte mas completo RFC 3548 para Base64, Base32 y Base16 para codificación y descodificación, incluyendo procesos de convertir caracteres a minúsculas y alfabetos alternativos. (Contribución de Barry Warsaw)

  • El módulo bisect ahora tiene una implementación C subyacente para mejorar el rendimiento. (Contribuido por Dmitry Vasiliev.)

  • Las colecciones CJKCodecs de códecs de Asia oriental, mantenidas por Hye-Shik Chang, se integraron en 2.4. Las nuevas codificaciones son:

  • Chino (PRC): gb2312, gbk, gb18030, big5hkscs, hz

  • Chino (República de China): big5, cp950

  • Japonés: cp932, euc-jis-2004, euc-jp, euc-jisx0213, iso-2022-jp,

    iso-2022-jp-1, iso-2022-jp-2, iso-2022-jp-3, iso-2022-jp-ext, iso-2022-jp-2004, shift-jis, shift-jisx0213, shift- jis-2004

  • Coreano: cp949, euc-kr, johab, iso-2022-kr

  • Se agregaron algunas otras codificaciones nuevas: HP Roman8, ISO_8859-11, ISO_8859-16, PCTP-154 y TIS-620.

  • The UTF-8 and UTF-16 codecs now cope better with receiving partial input. Previously the StreamReader class would try to read more data, making it impossible to resume decoding from the stream. The read() method will now return as much data as it can and future calls will resume decoding where previous ones left off. (Implemented by Walter Dörwald.)

  • There is a new collections module for various specialized collection datatypes. Currently it contains just one type, deque, a double-ended queue that supports efficiently adding and removing elements from either end:

    >>> from collections import deque
    >>> d = deque('ghi') # crea un nuevo deque con tres elementos
    >>> d.append('j') # agrega una nueva entrada al lado derecho
    >>> d.appendleft('f') # agrega una nueva entrada al lado izquierdo
    >>> d # muestra la representación del deque
    deque(['f', 'g', 'h', 'i', 'j'])
    >>> d.pop() # devuelve y elimina el elemento más a la derecha
    'j'
    >>> d.popleft() # devuelve y elimina el elemento más a la izquierda
    'f'
    >>> list(d) # lista el contenido del deque
    ['g', 'h', 'i']
    >>> 'h' in d # busca el deque
    True
    

    Several modules, such as the queue and threading modules, now take advantage of collections.deque for improved performance. (Contributed by Raymond Hettinger.)

  • Las clases ConfigParser se han mejorado ligeramente. El método read() ahora devuelve una lista de los archivos que se analizaron correctamente y el método set() genera TypeError si se le pasa un argumento value que no sea una cadena. (Contribuido por John Belmonte y David Goodger).

  • The curses module now supports the ncurses extension use_default_colors(). On platforms where the terminal supports transparency, this makes it possible to use a transparent background. (Contributed by Jörg Lehmann.)

  • The difflib module now includes an HtmlDiff class that creates an HTML table showing a side by side comparison of two versions of a text. (Contributed by Dan Gass.)

  • The email package was updated to version 3.0, which dropped various deprecated APIs and removes support for Python versions earlier than 2.3. The 3.0 version of the package uses a new incremental parser for MIME messages, available in the email.FeedParser module. The new parser doesn’t require reading the entire message into memory, and doesn’t raise exceptions if a message is malformed; instead it records any problems in the defect attribute of the message. (Developed by Anthony Baxter, Barry Warsaw, Thomas Wouters, and others.)

  • The heapq module has been converted to C. The resulting tenfold improvement in speed makes the module suitable for handling high volumes of data. In addition, the module has two new functions nlargest() and nsmallest() that use heaps to find the N largest or smallest values in a dataset without the expense of a full sort. (Contributed by Raymond Hettinger.)

  • The httplib module now contains constants for HTTP status codes defined in various HTTP-related RFC documents. Constants have names such as OK, CREATED, CONTINUE, and MOVED_PERMANENTLY; use pydoc to get a full list. (Contributed by Andrew Eland.)

  • The imaplib module now supports IMAP’s THREAD command (contributed by Yves Dionne) and new deleteacl() and myrights() methods (contributed by Arnaud Mazin).

  • The itertools module gained a groupby(iterable[, *func*]) function. iterable is something that can be iterated over to return a stream of elements, and the optional func parameter is a function that takes an element and returns a key value; if omitted, the key is simply the element itself. groupby() then groups the elements into subsequences which have matching values of the key, and returns a series of 2-tuples containing the key value and an iterator over the subsequence.

    Here’s an example to make this clearer. The key function simply returns whether a number is even or odd, so the result of groupby() is to return consecutive runs of odd or even numbers.

    >>> importar itertools
    >>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
    >>> para key_val, it en itertools.groupby(L, lambda x: x % 2):
    ... imprimir key_val, list(it)
    ...
    0 [2, 4, 6]
    1 [7]
    0 [8]
    1 [9, 11]
    0 [12, 14]
    >>>
    

    groupby() is typically used with sorted input. The logic for groupby() is similar to the Unix uniq filter which makes it handy for eliminating, counting, or identifying duplicate elements:

    >>> palabra = 'abracadabra'
    >>> letras = sorted(palabra) # Convierte una cadena en una lista ordenada de letras
    >>> letras
    ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
    >>> for k, g in itertools.groupby(letters):
    ... print k, list(g)
    ...
    a ['a', 'a', 'a', 'a', 'a']
    b ['b', 'b']
    c ['c']
    d ['d']
    r ['r', 'r']
    >>> # Lista de letras únicas
    >>> [k for k, g in groupby(letters)]
    ['a', 'b', 'c', 'd', 'r']
    >>> # Cuenta las ocurrencias de las letras
    >>> [(k, len(lista(g))) para k, g en groupby(letras)]
    [('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
    

    (Contribuido por Hye-Shik Chang.)

  • itertools también obtuvo una función denominada tee(iterator, N) que devuelve N independent iterators that replicate iterator. If N se omite, el valor predeterminado es 2.

    >>> L = [1,2,3]
    >>> i1, i2 = itertools.tee(L)
    >>> i1,i2
    (<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)
    >>> list(i1) # Ejecuta el primer iterador hasta el agotamiento
    [1, 2, 3]
    >>> list(i2) # Ejecuta el segundo iterador hasta el agotamiento
    [1, 2, 3]
    

    Note that tee() has to keep copies of the values returned by the iterator; in the worst case, it may need to keep all of them. This should therefore be used carefully if the leading iterator can run far ahead of the trailing iterator in a long stream of inputs. If the separation is large, then you might as well use list() instead. When the iterators track closely with one another, tee() is ideal. Possible applications include bookmarking, windowing, or lookahead iterators. (Contributed by Raymond Hettinger.)

  • A number of functions were added to the locale module, such as bind_textdomain_codeset() to specify a particular encoding and a family of l*gettext() functions that return messages in the chosen encoding. (Contributed by Gustavo Niemeyer.)

  • Some keyword arguments were added to the logging package’s basicConfig() function to simplify log configuration. The default behavior is to log messages to standard error, but various keyword arguments can be specified to log to a particular file, change the logging format, or set the logging level. For example:

    importar registro
    logging.basicConfig(filename='/var/log/application.log',
    level=0, # Registrar todos los mensajes
    format='%(levelname):%(process):%(thread):%(message)')
    

    Other additions to the logging package include a log(level, msg) convenience method, as well as a TimedRotatingFileHandler class that rotates its log files at a timed interval. The module already had RotatingFileHandler, which rotated logs once the file exceeded a certain size. Both classes derive from a new BaseRotatingHandler class that can be used to implement other rotating handlers.

    (Cambios implementados por Vinay Sajip.)

  • El módulo marshal ahora comparte cadenas internas al desempaquetar una estructura de datos. Esto puede reducir el tamaño de ciertas cadenas de pickle, pero el efecto principal es hacer que los archivos .pyc sean significativamente más pequeños. (Contribución de Martin von Löwis.)

  • The nntplib module’s NNTP class gained description() and descriptions() methods to retrieve newsgroup descriptions for a single group or for a range of groups. (Contributed by Jürgen A. Erhard.)

  • Se agregaron dos nuevas funciones al módulo operator, attrgetter(attr) y itemgetter(index). Ambas funciones devuelven invocables que toman un solo argumento y devuelven el atributo o elemento correspondiente; estos llamables son excelentes extractores de datos cuando se utilizan con map() o sorted(). Por ejemplo:

    >>> L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
    >>> map(operator.itemgetter(0), L)
    ['c', 'd', 'a', 'b']
    >>> map(operator.itemgetter(1), L)
    [2, 1, 4, 3]
    >>> sorted(L, key=operator.itemgetter(1)) # Ordenar la lista por el segundo elemento de la tupla
    [('d', 1), ('c', 2), ('b', 3), ('a', 4)]
    

    (Contribución de Raymond Hettinger.)

  • El módulo optparse se actualizó de varias formas. El módulo ahora pasa sus mensajes a través de gettext.gettext(), lo que permite internacionalizar los mensajes de error y ayuda de Optik. Los mensajes de ayuda para las opciones ahora pueden incluir la cadena '%default', que será reemplazada por el valor predeterminado de la opción. (Contribuido por Greg Ward.)

  • El plan a largo plazo es dejar obsoleto el módulo rfc822 en alguna versión futura de Python a favor del paquete email. Con este fin, se ha modificado la función email.Utils.formatdate para que pueda utilizarse como reemplazo de rfc822.formatdate(). Es posible que desee escribir un nuevo código de procesamiento de correo electrónico teniendo esto en cuenta. (Cambio implementado por Anthony Baxter).

  • Se agregó una nueva función urandom(n) al módulo os, que devuelve una cadena que contiene n bytes de datos aleatorios. Esta función proporciona acceso a fuentes de aleatoriedad específicas de la plataforma, como /dev/urandom en Linux o Windows CryptoAPI. (Contribuido por Trevor Perrin.)

  • Otra función nueva: os.path.lexists(path) devuelve verdadero si el archivo especificado por path exists, whether or not it’s a symbolic link. This differs from the existing ASDF01 function, which returns false if path es un enlace simbólico que apunta a un destino que no existe. (Contribuido por Beni Cherniavsky.)

  • A new getsid() function was added to the posix module that underlies the os module. (Contributed by J. Raynor.)

  • El módulo poplib ahora admite POP sobre SSL. (Contribuido por Héctor Urtubia.)

  • El módulo profile ahora puede perfilar funciones de extensión C. (Contribuido por Nick Bastin.)

  • The random module has a new method called getrandbits(N) that returns a long integer N bits in length. The existing randrange() method now uses getrandbits() where appropriate, making generation of arbitrarily large random numbers more efficient. (Contributed by Raymond Hettinger.)

  • El lenguaje de expresiones regulares aceptado por el módulo re se amplió con expresiones condicionales simples, escritas como (?(group)A|B). En su lugar, se utilizará group is either a numeric group ID or a group name defined with ASDF02 earlier in the expression. If the specified group matched, the regular expression pattern A will be tested against the string; if the group didn’t match, the pattern B. (Contribución de Gustavo Niemeyer.)

  • El módulo re ya no es recursivo, gracias a la enorme cantidad de trabajo de Gustavo Niemeyer. En un motor de expresión regular recursivo, ciertos patrones dan como resultado que se consuma una gran cantidad de espacio de pila de C y es posible desbordar la pila. Por ejemplo, si comparó una cadena de 30000 bytes de caracteres a con la expresión (a|b)+, se consumió un marco de pila por carácter. Python 2.3 intentó verificar el desbordamiento de la pila y generar una excepción RuntimeError, pero ciertos patrones podrían eludir la verificación y, si no tuvo suerte, Python podría segregar. El motor de expresiones regulares de Python 2.4 puede coincidir con este patrón sin problemas.

  • The signal module now performs tighter error-checking on the parameters to the signal.signal() function. For example, you can’t set a handler on the SIGKILL signal; previous versions of Python would quietly accept this, but 2.4 will raise a RuntimeError exception.

  • Two new functions were added to the socket module. socketpair() returns a pair of connected sockets and getservbyport(port) looks up the service name for a given port number. (Contributed by Dave Cole and Barry Warsaw.)

  • The sys.exitfunc() function has been deprecated. Code should be using the existing atexit module, which correctly handles calling multiple exit functions. Eventually sys.exitfunc() will become a purely internal interface, accessed only by atexit.

  • El módulo tarfile ahora genera archivos tar en formato GNU de forma predeterminada. (Contribución de Lars Gustäbel.)

  • The threading module now has an elegantly simple way to support thread-local data. The module contains a local class whose attribute values are local to different threads.

    importar subprocesos
    
    datos = threading.local()
    datos.number = 42
    datos.url = ('www.python.org', 80)
    

    Other threads can assign and retrieve their own values for the number and url attributes. You can subclass local to initialize attributes or to add methods. (Contributed by Jim Fulton.)

  • El módulo timeit ahora deshabilita automáticamente la recolección de basura periódica durante el ciclo de temporización. Este cambio hace que los tiempos consecutivos sean más comparables. (Contribuido por Raymond Hettinger.)

  • El módulo weakref ahora admite una variedad más amplia de objetos, incluidas funciones de Python, instancias de clases, conjuntos, frozensets, deques, matrices, archivos, sockets y objetos de patrones de expresión regular. (Contribuido por Raymond Hettinger.)

  • El módulo xmlrpclib ahora admite una extensión de múltiples llamadas para transmitir múltiples llamadas XML-RPC en una sola operación HTTP. (Contribuido por Brian Quinlan).

  • The mpz, rotor, and xreadlines modules have been removed.

cookielib

La biblioteca cookielib admite el manejo de cookies HTTP por parte del cliente, lo que refleja la compatibilidad con cookies del lado del servidor del módulo Cookie. Las cookies se almacenan en contenedores de cookies; la biblioteca almacena de forma transparente las cookies ofrecidas por el servidor web en el contenedor de cookies y recupera la cookie del contenedor cuando se conecta al servidor. Al igual que en los navegadores web, los objetos de política controlan si se aceptan o no las cookies.

Para almacenar cookies entre sesiones, se proporcionan dos implementaciones de tarros de cookies: una que almacena cookies en formato Netscape para que las aplicaciones puedan usar los archivos de cookies de Mozilla o Lynx, y otra que almacena cookies en el mismo formato que la biblioteca libwww de Perl.

urllib2 has been changed to interact with cookielib: HTTPCookieProcessor manages a cookie jar that is used when accessing URLs.

Este módulo fue una contribución de John J. Lee.

doctest

El módulo doctest se sometió a una refactorización considerable gracias a Edward Loper y Tim Peters. Las pruebas pueden ser tan simples como ejecutar doctest.testmod(), pero las refactorizaciones permiten personalizar el funcionamiento del módulo de varias formas.

The new DocTestFinder class extracts the tests from a given object’s docstrings:

def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y

finder = doctest.DocTestFinder()

# Obtener la lista de instancias de DocTest
tests = finder.find(f)

The new DocTestRunner class then runs individual tests and can produce a summary of the results:

runner = doctest.DocTestRunner()
para t en pruebas:
intentado, fallido = runner.run(t)

runner.summarize(verbose=1)

El ejemplo anterior produce la siguiente salida:

1 ítems pasaron todas las pruebas:
2 pruebas en f
2 pruebas en 1 ítem.
2 pasaron y 0 reprobaron.
Prueba aprobada.

DocTestRunner uses an instance of the OutputChecker class to compare the expected output with the actual output. This class takes a number of different flags that customize its behaviour; ambitious users can also write a completely new subclass of OutputChecker.

El comprobador de salida predeterminado proporciona una serie de funciones útiles. Por ejemplo, con el indicador de opción doctest.ELLIPSIS, una elipsis (...) en la salida esperada coincide con cualquier subcadena, lo que facilita la adaptación de salidas que varían en formas menores:

def o (n):
    """>>> o(1)
<__main__.C instance at 0x...>
>>>
"""

Otra cadena especial, <BLANKLINE>, coincide con una línea en blanco:

def p (n):
    """>>> p(1)
<BLANKLINE>
>>>
"""

Otra nueva capacidad es producir una visualización de estilo diff de la salida especificando doctest.REPORT_UDIFF (diferencias unificadas), doctest.REPORT_CDIFF (diferencias de contexto), o doctest.REPORT_NDIFF Indicadores de opción (estilo delta). Por ejemplo:

def g (n):
    """>>> g(4)
here
is
a
lengthy
>>>"""
    L = 'here is a rather lengthy list of words'.split()
    for word in L[:n]:
        print word

Al ejecutar las pruebas de la función anterior con doctest.REPORT_UDIFF especificado, obtiene el siguiente resultado:

**********************************************************************
File "t.py", line 15, in g
Failed example:
    g(4)
Differences (unified diff with -expected +actual):
    @@ -2,3 +2,3 @@
     is
     a
    -lengthy
    +rather
**********************************************************************

Cambios en la API de Build y C

Algunos de los cambios en el proceso de compilación de Python y en la API de C son:

  • Se agregaron tres nuevas macros de conveniencia para valores de retorno comunes de funciones de extensión: Py_RETURN_NONE, Py_RETURN_TRUE, y Py_RETURN_FALSE. (Contribuido por Brett Cannon.)

  • Otra macro nueva, Py_CLEAR, reduce el recuento de referencias de obj y establece obj en el puntero nulo. (Aportado por Jim Fulton.)

  • Una nueva función, PyTuple_Pack(N, obj1, obj2, ..., objN), construye tuplas a partir de una lista de argumentos de longitud variable de objetos Python. (Contribuido por Raymond Hettinger.)

  • Una nueva función, PyDict_Contains(d, k), implementa búsquedas rápidas de diccionarios sin enmascarar las excepciones que surgen durante el proceso de búsqueda. (Contribuido por Raymond Hettinger.)

  • The Py_IS_NAN macro returns 1 if its float or double argument X is a NaN. (Contributed by Tim Peters.)

  • El código C puede evitar el bloqueo innecesario mediante el uso de la nueva función PyEval_ThreadsInitialized() para saber si se ha realizado alguna operación de subproceso. Si esta función devuelve falso, no se necesitan operaciones de bloqueo. (Contribuido por Nick Coghlan.)

  • Una nueva función, PyArg_VaParseTupleAndKeywords(), es la misma que PyArg_ParseTupleAndKeywords() pero toma un va_list en lugar de varios argumentos. (Contribuido por Greg Chapman.)

  • A new method flag, METH_COEXIST, allows a function defined in slots to co-exist with a PyCFunction having the same name. This can halve the access time for a method such as set.__contains__(). (Contributed by Raymond Hettinger.)

  • Python ahora se puede construir con perfiles adicionales para el intérprete en sí, con la intención de ayudar a las personas que desarrollan el núcleo de Python. Proporcionar - enable-profiling al configure script le permitirá perfilar el intérprete con gprof, y proporcionar el - with-tsc switch permite la creación de perfiles utilizando el registro de contador de marcas de tiempo del Pentium. Tenga en cuenta que el conmutador - with-tsc tiene un nombre ligeramente incorrecto, porque la función de creación de perfiles también funciona en la plataforma PowerPC, aunque la arquitectura del procesador no llama a ese registro» el registro TSC «. (Contribuido por Jeremy Hylton.)

  • The tracebackobject type has been renamed to PyTracebackObject.

Cambios específicos del puerto

  • El puerto de Windows ahora se construye bajo MSVC ++ 7.1 y también con la versión 6. (Contribuido por Martin von Löwis).

Portar a Python 2.4

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

  • Los desplazamientos a la izquierda y las constantes hexadecimales / octales que son demasiado grandes ya no activan un FutureWarning y devuelven un valor limitado a 32 o 64 bits; en su lugar, devuelven un entero largo.

  • Integer operations will no longer trigger an OverflowWarning. The OverflowWarning warning will disappear in Python 2.5.

  • The zip() built-in function and itertools.izip() now return an empty list instead of raising a TypeError exception if called with no arguments.

  • You can no longer compare the date and datetime instances provided by the datetime module. Two instances of different classes will now always be unequal, and relative comparisons (<, >) will raise a TypeError.

  • dircache.listdir() ahora pasa excepciones a la persona que llama en lugar de devolver listas vacías.

  • LexicalHandler.startDTD used to receive the public and system IDs in the wrong order. This has been corrected; applications relying on the wrong order need to be fixed.

  • fcntl.ioctl() ahora advierte si el argumento mutate se omite y es relevante.

  • El módulo tarfile ahora genera archivos de GNU tar-formato por defecto.

  • Encontrar un error al importar un módulo ya no deja un objeto de módulo parcialmente inicializado en sys.modules.

  • None ahora es una constante; El código que une un nuevo valor al nombre None ahora es un error de sintaxis.

  • The signal.signal() function now raises a RuntimeError exception for certain illegal values; previously these errors would pass silently. For example, you can no longer set a handler on the SIGKILL signal.

Agradecimientos

El autor desea agradecer a las siguientes personas por ofrecer sugerencias, correcciones y ayuda con varios borradores de este artículo: Koray Can, Hye-Shik Chang, Michael Dyck, Raymond Hettinger, Brian Hurt, Hamish Lawson, Fredrik Lundh, Sean Reifschneider, Sadruddin Rejeb.