Subsecciones


10. Viaje rápido por la biblioteca estándar


10.1 Interfaz con el sistema operativo

El módulo os proporciona funciones para interactuar con el sistema operativo:

>>> import os
>>> os.system('time 0:02')
0
>>> os.getcwd()      # Devuelve el directorio de trabajo actual
'C:\\Python24'
>>> os.chdir('/server/accesslogs')

Asegúrate de usar el estilo "import os" en lugar de "from os import *". Esto evitará que os.open() oculte la función iterna open(), que tiene un funcionamiento muy diferente.

Las funciones internas dir() y help() son útiles como ayudantes interactivos para trabajar con módulos grandes, como os:

>>> import os
>>> dir(os)
<devuelve una lista de todas las funciones del módulo>
>>> help(os)
<devuelve un extenso manual creado a partir de las cadenas de documentación del módulo>

Para tareas de gestión de ficheros y directorios diarias, el módulo shutil proporciona una interfaz de nivel más alto, más fácil de usar:

>>> import shutil
>>> shutil.copyfile('datos.db', 'copia.db')
>>> shutil.move('/build/ejecutables', 'dirinstalacion')


10.2 Comodines de ficheros

El módulo glob proporciona una función para crear listas de ficheros a partir de búsquedas con comodines por directorios:

>>> import glob
>>> glob.glob('*.py')
['primes.py', 'random.py', 'quote.py']


10.3 Argumentos de la línea de órdenes

Los guiones de utillería usuales necesitan procesar argumentos de la línea de órdenes a menudo. Estos argumentos se guardan en el atributo argv del módulo sys como una lista. Por ejemplo, éste es el resultado de ejecutar "python demo.py un dos tres" en la línea de órdenes:

>>> import sys
>>> print sys.argv
['demo.py', 'un', 'dos', 'tres']

El módulo getopt procesa sys.argv utilizando las convenciones de la función getopt() de Unix. El módulo optparse proporciona un procesado de línea de órdenes más potente y flexible.


10.4 Redirección de la salida de errores y terminación del programa

El módulo sys también tiene atributos stdin, stdout y stderr. Éste último es útil para emitir mensajes de error para hacerlos visibles si se ha redirigido stdout:

>>> sys.stderr.write('Aviso: No hay fichero de registro, genero uno nuevo\n')
Aviso: No hay fichero de registro, genero uno nuevo

El modo más simple de terminar un guiones es usar "sys.exit()".


10.5 Búsqueda de patrones de cadenas

El módulo re proporciona herramientas de expresiones regulares para procesado avanzado de cadenas. En problemas que requieren búsquedas y manipulaciones complejas, las expresiones regulares proporcionan soluciones breves y optimizadas:

>>> import re
>>> re.findall(r'\bq[a-z]*', 'sabes lo que pasa cuando dices que me quieres')
['que', 'que', 'quieres']
>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'arde la calle al sol de de poniente')
'arde la calle al sol de poniente'

Si sólo se necesitan cosas simples, se prefieren los métodos de las cadenas porque son más sencillos de leer y depurar:

>>> 'cien siluetas'.replace('cien', 'mil')
'mil siluetas'


10.6 Matemáticas

El módulo math permite el acceso a las funciones de la biblioteca C subyacente para las matemáticas de coma flotante:

>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757
>>> math.log(1024, 2)
10.0

El módulo random proporciona herramientas para hacer selecciones aleatorias:

>>> import random
>>> random.choice(['manzana', 'pera', 'banana'])
'manzana'
>>> random.sample(xrange(100), 10)   # muestreo sin reemplazo
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random()    # número en coma flotante aleatorio
0.17970987693706186
>>> random.randrange(6)    # entero aleatorio elegido de range(6)
4


10.7 Acceso a internet

Hay varios módulos para acceder a internet y procesar protocolos de internet. Dos de los más sencillos son urllib2 para recuperar datos de URLs y smtplib para enviar correo:

>>> import urllib2
>>> for linea in urllib2.urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
...     if 'EST' in linea:      # Buscar Eastern Standard Time
...         print linea
    
<BR>Nov. 25, 09:43:32 PM EST

>>> import smtplib
>>> servidor = smtplib.SMTP('localhost')
>>> servidor.sendmail('adivino@example.org', 'jcesar@example.org',
"""To: jcesar@example.org
From: adivino@example.org

Guardaos de los idus de marzo.
""")
>>> server.quit()


10.8 Fechas y horas

El módulo datetime proporciona clases para manipular fechas y horas en operaciones sencillas y complejas. Aunque da soporte a la aritmética de fechas y horas, el énfasis de la implementación es la extracción eficaz de los miembros para formato y manipulación de salida. El módulo también proporciona objetos sensibles a los husos horarios.

# es fácil construir y dar formato a fechas
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'

# las fechas tienen aritmética de calendario
>>> cumple = date(1967, 11, 10)
>>> edad = now - cumple
>>> edad.days
13592


10.9 Compresión de datos

Hay módulos para gestionar los formatos comunes de archivado y compresión, incluyendo:

zlib, gzip, bz2, zipfile, and tarfile.

>>> import zlib
>>> s = 'campana sobre campana y sobre campana otra'
>>> len(s)
42
>>> t = zlib.compress(s)
>>> len(t)
31
>>> zlib.decompress(t)
'campana sobre campana y sobre campana otra'
>>> zlib.crc32(s)
1480756653


10.10 Medidas de rendimiento

Algunos usuarios de Python desarrollan un profundo interés en conocer el rendimiento comparativo de diferentes ataques al mismo problema. Python proporciona una herramienta de medida que responde a estas cuestiones de inmediato.

Por ejemplo, es tentador utilizar la característica de empaquetar y desempaquetar tuplas en lugar del método tradicional para intercambiar argumentos. El módulo timeit rápidamente demuestra una ligera ventaja de rendimiento:

>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791

A diferencia de la granularidad de timeit, los módulos profile y pstats proporcionan herramientas para identificar secciones críticas en cuanto al tiempo en bloques de código mayores.


10.11 Control de calidad

Una posible solución para desarrollar software de alta calidad es escribir pruebas para cada función según se desarrolla y ejecutar a menudo dichas pruebas a lo largo del proceso de desarrollo.

El módulo doctest proporciona una herramienta para rastrear un módulo y las pruebas de validación incrustados en las cadenas de documentación de un programa. La construcción de las pruebas es una simple tarea de cortaypega en las cadenas de documentación. Esto mejora la documentación proporcionando al usuario un ejemplo y permite al módulo doctest asegurar que el código permanece fiel a la documentación:

def media(valores):
    """Calcula la media aritmética de una lista de números.

    >>> print media([20, 30, 70])
    40.0
    """
    return sum(valores, 0.0) / len(valores)

import doctest
doctest.testmod()   # valida automáticamente las pruebas incrustadas

El módulo unittest requiere algo más de esfuerzo que el módulo doctest, pero permite mantener un conjunto completo de pruebas en un fichero aparte:

import unittest

class TestStatisticalFunctions(unittest.TestCase):

    def test_average(self):
        self.assertEqual(average([20, 30, 70]), 40.0)
        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
        self.assertRaises(ZeroDivisionError, average, [])
        self.assertRaises(TypeError, average, 20, 30, 70)

unittest.main() # Para llamar a todas las pruebas, desde la línea de órdenes


10.12 Pilas incluidas

Python mantiene una filosofía de ``pilas incluidas''. Esto se percibe mejor a partir de la complejidad y robustez de su paquetes más grandes. Por ejemplo:

Consultar en Acerca de este documento... información para sugerir cambios.