Como es habitual, la biblioteca estándar de Python sufrió mejoras
y corrección de errores. He aquí una lista, incompleta, de los cambios
más notables, por orden alfabético del nombre del módulo afectado.
En el fichero Misc/NEWS del árbol de las fuentes
una lista más exhaustiva de los cambios y en los registros de CVS
están todos los detalles.
- En el módulo asyncore, la función loop() ahora
tiene un parámetro count que permite realizar un número limitado
de pasadas por el bucle de muestreo. El valor predeterminado sigue
siendo un bucle infinito.
- El módulo base64 dispone de soporte RFC 3548 más completo
para codificación y descodificación Base64, Base32 y Base16, incluyendo
cambios de mayúsculas/minúsculas y alfabetos alternativos opcionales.
(Contribución de Barry Warsaw.)
- El módulo bisect cuenta ahora con una implementación en C
que mejora su rendimiento.
(Contribución de Dmitry Vasiliev.)
- Se integraron en la versión 2.4 las colecciones CJKCodecs de codecs
del Este asiático, mantenidas por Hye-Shik Chang.
Las nuevas codificaciones son:
- Chino (PRC): gb2312, gbk, gb18030, big5hkscs, hz
- Chino (ROC): 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 han añadido algunas codificaciones nuevas: HP Roman8,
ISO_8859-11, ISO_8859-16, PCTP-154 y TIS-620.
- Los codecs de UTF-8 y UTF-16 gestionan mejor la recepción parcial
de datos. Antes, la clase StreamReader intentaba leer más
datos, imposibilitando reanudar la descodificación del flujo de datos.
Ahora el método read() devolverá tantos datos como pueda y
las siguientes llamadas reaunudarán la descodificación donde se
quedaron las anteriores.
(Implementada por Walter Dörwald.)
- Hay un nuevo módulo collections que contiene diversos
tipos de datos colección especializados. Por el momento, sólo
contiene un tipo, deque, una cola de dos extremos que
da soporte a añadir y quitar elementos eficientemente de cualquiera
de los extremos:
>>> from collections import deque
>>> d = deque('ghi') # genera una nueva deque con tres elementos
>>> d.append('j') # añade un nuevo elemento por la derecha
>>> d.appendleft('f') # añade uno por la izquierda
>>> d # muestra el contenido de la deque
deque(['f', 'g', 'h', 'i', 'j'])
>>> d.pop() # obtiene y elimina el elemento de la derecha
'j'
>>> d.popleft() # obtiene y elimina el elemento de la derecha
'f'
>>> list(d) # muestra la deque convertida en lista
['g', 'h', 'i']
>>> 'h' in d # buscar en la deque
True
Varios módulos, como Queue y threading, ahora
aprovechan collections.deque para mejorar su rendimiento.
(Contribución de Raymond Hettinger.)
- Se han mejorado las clases de ConfigParser. El método
read() ahora devuelve una lista de los ficheros que se
analizaron con éxito y el método set() lanza
TypeError si recibe un argumento value que no sea
una cadena (Contribución de John Belmonte y David Goodger.)
- El módulo curses ahora ofrece la extensión de ncurses
use_default_colors(). En plataformas cuyo terminal disponga
de transparencia, esto posibilita utilizar un fondo transparente.
(Contribución de Jörg Lehmann.)
- El módulo difflib ahora incluye una clase HtmlDiff
que genera una tabla HTML que muestra una comparación de dos versiones
de un texto. (Contribución de Dan Gass.)
- Se ha actualizado el paquete email a la versión 3.0,
abandonando ciertas APIs obsoletas y el soporte de versiones de Python
anteriores a la 2.3. La versión 3.0 utiliza un nuevo analizador incremental
para los mensajes MIME, disponible en el módulo email.FeedParser.
El nuevo analizador no exige leer el mensaje entero en memoria y no lanza
excepciones si el mensaje no está bien formado, sino que registra los
posibles problemas en el atributo defect del mensaje.
(Desarrolado por Anthony
Baxter, Barry Warsaw, Thomas Wouters, entre otros.)
- Se ha convertido el módulo heapq a C. Al acelerarse en
un factor de diez, se ha hecho aceptable su uso con volúmenes de carga
elevados. Además, el módulo cuenta con dos nuevas funciones,
nlargest() y nsmallest(), que usan montículos
para encontrar los N mayores o menores valores de un juego de datos sin
tener que ordenar el conjunto completo.
(Contribuición de Raymond Hettinger.)
- El módulo httplib ahora contiene constantes para los códigos de
estado definidos en diversos RFC relativos a HTTP. Las constantes tienen
nombres del estilo de OK, CREATED,
CONTINUE o MOVED_PERMANENTLY. Se puede obtener
la lista completa usando pydoc. (Contribución de Andrew Eland.)
- El módulo imaplib ahora soporta la orden de IMAP THREAD
(contribución de Yves Dionne) y cuenta con los nuevos métodos
deleteacl() y myrights() (contribución de Arnaud Mazin).
- El módulo itertools mejora con una función
groupby(iterable[, func]).
iterable es algún valor sobre el que se puede iterar para
obtener un flujo de elementos y el parámetro opcional func
es una función que toma un elemento y devuelve un valor clave; si
se omite, la clave es el propio elemento. groupby() agrupa
los elementos en subsecuencias que contienen valores iguales de clave
y devuelve una serie de duplas que contienen la clave y un iterador
de la subsecuencia.
Intentaremos aclarar esto con un ejemplo. La función key
simplemente devuelve si el número es par o impar, para que el resultado
de groupby() sea filas consecutivas de números impares o pares.
>>> import itertools
>>> L = [2, 4, 6, 7, 8, 9, 11, 12, 14]
>>> for key_val, it in itertools.groupby(L, lambda x: x % 2):
... print key_val, list(it)
...
0 [2, 4, 6]
1 [7]
0 [8]
1 [9, 11]
0 [12, 14]
>>>
A menudo, groupby() se aplica sobre una entrada ordenada. La lógica
de groupby() se parece a la de el filtro de Unix uniq
,
lo que hace que sea de mucha ayuda para eliminar, contar o identificar duplicados:
>>> palabra = 'abracadabra'
>>> letras = sorted(palabra) # Saca una lista ordenada de sus letras
>>> letras
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd', 'r', 'r']
>>> for k, g in itertools.groupby(letras):
... print k, list(g)
...
a ['a', 'a', 'a', 'a', 'a']
b ['b', 'b']
c ['c']
d ['d']
r ['r', 'r']
>>> # Lista de letras sin repetir
>>> [k for k, g in groupby(letras)]
['a', 'b', 'c', 'd', 'r']
>>> # Contar apariciones de una letra
>>> [(k, len(list(g))) for k, g in groupby(letras)]
[('a', 5), ('b', 2), ('c', 1), ('d', 1), ('r', 2)]
(Contribución de Hye-Shik Chang.)
- itertools también cuenta con una nueva función
tee(iterator, N) que devuelve N iteradores
independientes, réplica de iterator. Si se omite N se devuelven
dos copias.
>>> L = [1,2,3]
>>> i1, i2 = itertools.tee(L)
>>> i1,i2
(<itertools.tee object at 0x402c2080>, <itertools.tee object at 0x402c2090>)
>>> list(i1) # Recorre el primer iterador hasta agotarlo
[1, 2, 3]
>>> list(i2) # Recorre el segundo iterador hasta agotarlo
[1, 2, 3]
>
Hay que destacar que tee() debe mantener copias de los valores
devueltos por el iterador y, en el peor de los casos, puede que tenga que
mantener copia de todos. Se ha de evaluar detenidamente si uno de los
iteradores va a adelantar mucho al último en un flujo de entrada largo.
Si la separación se hace muy grande, puede convenir usar list()
mejor. Cuando los iteradores se mantienen casi parejos, el uso de
tee() es óptimo. Las posibles aplicaciones incluyen marcado de
texto, ventanas de señal o iteradores con acceso a elementos futuros.
(Contribución de Raymond Hettinger.)
- Se han añadido varias funciones al módulo locale, como
bind_textdomain_codeset() para especificar una codificación particular
y una familia de funciones l*gettext() que devuelven los mensajes
en la codificación elegida.
(Contribución de Gustavo Niemeyer.)
- Se han añadido argumentos con nombre a la función basicConfig
del paquete logging para simplificar la configuración del registro.
El comportamiento predeterminado es registrar los mensajes al flujo de error
estándar, pero se pueden especificar varios argumentos con nombre para
registrar sobre un fichero particular, cambiar el formato de registro o
establecer el nivel de registro. Por ejemplo:
import logging
logging.basicConfig(filename='/var/log/aplicacion.log',
level=0, # Registrar todos los mensajes
format='%(levelname):%(process):%(thread):%(message)')
Otras mejoras del paquete logging son el método de servicio
log(level, msg), además de una clase
TimedRotatingFileHandler que rota sus ficheros de registro a
un intervalo dado. El módulo ya contaba con RotatingFileHandler,
que rotaba los registros al alcanzar un tamaño dado. Las dos clases se
derivan de una clase nueva BaseRotatingHandler que se puede
utilizar para implementar otros gestores de rotación.
(Cambios implementados por Vinay Sajip.)
- El módulo marshal ahora comparte las cadenas internadas al
desempaquetar una estructura de datos. Esto puede suponer una reducción
en el tamaño de ciertas cadenas estibadas (pickled), pero el principal
efecto es el de reducir significativamente el tamaño de los archivos
.pyc.
(Contribución de Martin von Loewis.)
- En el módulo nntplib, la clase NNTP se mejora con
los métodos description() y descriptions() para obtener
las descripciones de un solo grupo o varios, respectivamente.
(Contribución de Jürgen A. Erhard.)
- Se ha añadido dos nuevas funciones al módulo operator,
attrgetter(attr) y itemgetter(index).
Las dos devuelven objetos invocables que toman un solo argumento y devuelven
el atributo o elemento correspondiente; esto las hace idóneas para extraer
datos al usar 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)) # Ordena la lista por el segundo elemento
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]
(Contribución de Raymond Hettinger.)
- El módulo optparse ha sufrido diversas mejoras. El módulo
ahora pasa sus mensajes por gettext.gettext(), posibilitando
internacionalizar la ayuda y los mensajes de error de Optik. Los mensajes
de ayuda de las opciones ahora pueden incluir la cadena
'%default'
, que será sustituida por el valor predeterminado de
la opción (contribución de Greg Ward).
- El plan a largo plazo es declarar obsoleto el módulo rfc822
en una versión futura de Python, en favor del paquete email.
Con esto como objetivo, se ha cambiado la función
email.Utils.formatdate() para que sea un reemplazo adecuado
de rfc822.formatdate(). Es deseable que el código que se escriba
de ahora en adelante tenga esto presente. (Cambio implementado por Anthony
Baxter.)
- Se ha añadido una función nueva, urandom(n),
al módulo os, que devuelve una cadena de n bytes
de datos aleatorios. Esta función proporciona un acceso dependiente
de la plataforma a fuentes de aleatoriedad, como /dev/urandom
en Linux o la CryptoAPI de Windows. (Contribución de Trevor Perrin.)
- Otra función nueva: os.path.lexists(path)
devuelve verdadero si existe el fichero especificado por path,
sea o no un enlace simbólico. Esto difiere de la función existente
os.path.exists(path), que devuelve falso si
path es un enlace simbólico que apunta a un destino inexistente.
(Contribución de Beni Cherniavsky.)
- Se añadió una nueva función getsid() al módulo
posix subyacente al módulo os.
(Contribución de J. Raynor.)
- El módulo poplib ahora da soporte a POP sobre SSL. (Contribución
de Héctor Urtubia.)
- El módulo profile ahora puede perfilar funciones de extensión
en C.
(Contribución de Nick Bastin.)
- El módulo random ahora cuenta con un nuevo método
getrandbits(N) que devuelve un entero largo de N
bits de longitud. El método existente randrange() ahora usa
getrandbits() donde ha lugar, haciendo más eficaz la generación
de números aleatorios arbitrariamente grandes. (Contribución de
Raymond Hettinger.)
- Se ha extendido el lenguaje de expresiones regulares aceptado por
el módulo re con expresiones condicionales simples, escritas
como (?(group)A|B). group es un ID
de grupo numérico o un nombre de grupo definido antes con
(?P<group>...) dentro de la expresión. Si coincide el grupo
especificado, se comprobará la expresión regular A contra la
cadena; si no, se utilizará el patrón B en su lugar.
(Contribución de Gustavo Niemeyer.)
- El módulo re deja de ser recursivo, gracias a un trabajo
titánico de Gustavo Niemeyer. En un motor de expresiones regulares recursivo,
ciertos patrones causan que se ocupe una gran cantidad de la pila de C,
por lo que era posible desbordarla. Por ejemplo, a comparar una cadena de
30000 caracteres "a" contra la expresión (a|b)+, se consumía
un marco de pila por carácter. Python 2.3 intentaba verificar el
desbordamiento y lanzar una excepción RuntimeError,
pero ciertos patrones desafortunados podrían saltarse la comprobación
y causar un fallo de segmentación en Python. El motor de expresiones
regulares de Python puede comprobar este tipo de patrones sin problemas.
- El módulo signal ahora realiza comprobaciones de errores
más estrictas sobre los parámetros de la función signal.signal().
Por ejemplo, no se puede establecer un gestor de la señal
SIGKILL; las versiones anteriores de Python aceptaban esto
silenciosamente, pero la 2.4 hará saltar una excepción
RuntimeError.
- Se han añadido dos nuevas funciones al módulo socket.
socketpair() devuelve un par de zócalos conectados y
getservbyport(port) busca el nombre de servicio
para un número de puerto dado.
(Contribución de Dave Cole y Barry Warsaw.)
- La función sys.exitfunc() se ha abandonado. El código
deberá adaptarse a usar el módulo existente atexit,
que gestiona correctamente múltiples funciones de salida. Al final,
sys.exitfunc() se convertirá simplemente en una interfaz
estrictamente interna, accesible sólo desde el módulo atexit.
- El módulo tarfile ahora genera ficheros tar de formato GNU
de manera predeterminada. (Contribución de Lars Gustaebel.)
- El módulo threading ahora cuenta con un sistema elegantemente
simple de proporcionar datos locales al hilo. El módulo contiene una clase
local cuyos valores de atributo son locales al hilo.
import threading
data = threading.local()
data.number = 42
data.url = ('www.python.org', 80)
Otros hilos pueden asignar y recuperar sus propios valores a los
atributos number y url. Se puede derivar
local para inicializar atributos o añadir métodos.
(Contribución de Jim Fulton.)
- El módulo timeit ahora desactiva automáticamente la recolección
periódica de basura durante el bucle de temporización. Estos cambios hacen
más comparables medidas consecutivas. (Contribución de Raymond Hettinger.)
- El módulo weakref ahora da soporte a una variedad ampliada de
objetos, incluyendo funciones de Python, instancias de clases, conjuntos,
conjuntos congelados, deques, matrices, ficheros, zócalos y objetos patrón
de expresiones regulares.
(Contribución de Raymond Hettinger.)
- El módulo xmlrpclib ahora dispone de una extensión multillamada
para transmitir múltiples llamadas XML-RPC en una sola operación HTTP.
(Contribución de Brian Quinlan.)
- Se han retirado los módulos mpz, rotor y
xreadlines.
La biblioteca cookielib permite la gestión en el lado del cliente
de cookies (galletas) HTTP, a imagen del módulo Cookie de gestión de cookies
del lado del servidor. Las cookies se guardan en tarros de cookies; la
biblioteca almacena transparentemente las cookies ofrecidas por el servidor
web al conectarse al servidor. Como en los navegadores normales, hay un objeto
de política que controla si se aceptan o no las cookies.
Para guardar las cookies entre sesiones, se proporcionan dos implementaciones
de tarros de cookies: Una almacena las cookies en el formato Netscape,
para que las aplicaciones puedan utilizar los ficheros de cookies de
Mozilla o Lynx, y otra que almacena las cookies en el mismo formato que
la biblioteca de Perl libwww.
Se ha cambiado el módulo urllib2 para interactuar con cookielib:
HTTPCookieProcessor gestiona un tarro de cookies que se utiliza al acceder
a URLs.
(Contribución de John J. Lee.)
El módulo doctest sufrió una considerable refactorización gracias
a Edward Loper y Tim Peters. Las pruebas pueden ser tan sencillas como ejecutar
doctest.testmod(), pero las refactorizaciones permiten adaptar el
funcionamiento del módulo de diversas maneras.
La nueva clase DocTestFinder extrae las pruebas de las cadenas de
documentación de un objeto dado:
def f (x, y):
""">>> f(2,2)
4
>>> f(3,2)
6
"""
return x*y
buscador = doctest.DocTestFinder()
# Obtener la lista de instancias de DocTest
pruebas = buscador.find(f)
Entonces, la nueva clase DocTestRunner ejecuta las pruebas
individuales y puede producir un resumen de los resultados:
ejecutor = doctest.DocTestRunner()
for t in tests:
tried, failed = ejecutor.run(t)
ejecutor.summarize(verbose=1)
El ejemplo produce la siguiente salida:
1 items passed all tests:
2 tests in f
2 tests in 1 items.
2 passed and 0 failed.
Test passed.
DocTestRunner usa una instancia de la clase OutputChecker
para comparar la salida esperada con la salida real. Esta clase admite
diferentes indicadores que personalizan su comportamiento; los
usuarios ambiciosos también pueden escribir una subclase de
OutputChecker completamente nueva.
El comprobador de salida predefinido ofrece características muy útiles.
Por ejemplo, con el indicador de opción doctest.ELLIPSIS,
los puntos suspensivos ("...") de la entrada pueden coincidir
con cualquier subcadena, facilitando acomodar salidas que varían ligeramente:
def o (n):
""">>> o(1)
<__main__.C instance at 0x...>
>>>
"""
Hay otra cadena, "<BLANKLINE>", que coincide con una línea en blanco:
def p (n):
""">>> p(1)
<BLANKLINE>
>>>
"""
Otra posibilidad nueva es la de producir una presentación tipo diff de la
salida especificando los indicadores de opción
doctest.REPORT_UDIFF (unificados),
doctest.REPORT_CDIFF (de contexto) o
doctest.REPORT_NDIFF (tipo delta). Por ejemplo:
def g (n):
""">>> g(4)
bajel
pirata
que
llaman
>>>"""
L = 'bajel pirata que llaman por su bravura el temido'.split()
for palabra in L[:n]:
print palabra
Al ejecutar esto especificando doctest.REPORT_UDIFF,
se 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 @@
pirata
que
-laman
+llaman
**********************************************************************
Consultar en Acerca de este documento... información para sugerir cambios.