Guía de aprendizaje de Python

Si sales del int�rprete de Python y vuelves a entrar, las definiciones que hayas hecho (funciones y variables) se pierden. Por ello, si quieres escribir un programa algo m�s largo, ser� mejor que utilices un editor de texto para preparar la entrada del int�rprete y ejecutarlo con ese fichero como entrada. Esto se llama crear un guion. Seg�n vayan creciendo los programas, puede que quieras dividirlos en varios ficheros para facilitar el mantenimiento. Puede que tambi�n quieras utilizar una funci�n que has escrito en varios programas sin tener que copiar su definici�n a cada programa.

Para lograr esto, Python tiene un modo de poner definiciones en un fichero y utilizarlas en un guion o en una instancia interactiva del int�rprete. Tal fichero se llama m�dulo; las definiciones de un m�dulo se pueden importar a otros m�dulos o al m�dulo principal (la colecci�n de variables accesible desde un guion ejecutado desde el nivel superior y en el modo de calculadora).

Un m�dulo es un fichero que contiene definiciones y sentencias Python. El nombre del fichero es el nombre del m�dulo con el sufijo �.py�. Dentro de un m�dulo, el nombre del m�dulo (como cadena) es accesible mediante la variable global __name__. Por ejemplo, utiliza tu editor de texto favorito para crear un fichero llamado �fibo.py� en el directorio actual, con el siguiente contenido:

# M�dulo de los n�meros de Fibonacci
def fib(n): # escribir la serie de Fibonacci hasta n
    a, b = 0, 1
    while b < n:
        print b,
        a, b = b, a+b
def fib2(n): # devolver la serie de Fibonacci hasta n
    resultado = []
    a, b = 0, 1
    while b < n:
        resultado.append(b)
        a, b = b, a+b
    return resultado

Ahora entra en el int�rprete de Python e importa este m�dulo con la siguiente orden:

>>> import fibo

Esto no introduce los nombres de las funciones definidas en fibo directamente en la tabla de s�mbolos actual; s�lo introduce el nombre del m�dulo fibo. Utilizando el nombre del m�dulo puedes acceder a las funciones:

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
�fibo�

Si pretendes utilizar una funci�n a menudo, la puedes asignar a un nombre local:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

.�M�s sobre los m�dulos

Un m�dulo puede contener sentencias ejecutables adem�s de definiciones de funciones. Estas sentencias sirven para inicializar el m�dulo. S�lo se ejecutan la primera vez que se importa el m�dulo en alguna parte.

Cada m�dulo tiene su propia tabla de s�mbolos, que utilizan todas las funciones definidas por el m�dulo como tabla de s�mbolos global. Por ello, el autor de un m�dulo puede utilizar variables globales dentro del m�dulo sin preocuparse por conflictos con las variables globales de un usuario del m�dulo. Por otra parte, si sabes lo que haces, puedes tocar las variables globales de un m�dulo con la misma notaci�n utilizada para referirse a sus funciones, nombre-Mod. nombreElem.

Los m�dulos pueden importar otros m�dulos. Es una costumbre no obligatoria colocar todas las sentencias import al principio del m�dulo (o guion). Los nombres del m�dulo importado se colocan en la tabla de s�mbolos global del m�dulo (o guion) que lo importa.

Existe una variaci�n de la sentencia import que importa los nombres de un m�dulo directamente a la tabla de s�mbolos del m�dulo que lo importa. Por ejemplo:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Esto no introduce el nombre del m�dulo del que se toman los elementos importados en la tabla de s�mbolos local (por lo que, en el ejemplo, no est� definido fibo).

Adem�s, existe una variaci�n que importa todos los nombres que define un m�dulo:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Esto importa todos los nombres, excepto los que empiezan por un guion bajo (_).

.�El camino de b�squeda de m�dulos

Cuando se importa un m�dulo denominado fiambre, el int�rprete busca un fichero denominado �fiambre.py� en el directorio actual y, luego, en la lista de directorios especificada por la variable de entorno $PYTHONPATH. Tiene la misma sintaxis que la variable de l�nea de �rdenes $PATH de UNIX, que es una lista de nombres de directorios. Cuando $PYTHONPATH no tiene ning�n valor o no se encuentra el fichero, se contin�a la b�squeda en un camino dependiente de la instalaci�n. En UNIX, normalmente es �.:/usr/local/lib/python�.

En realidad, se buscan los m�dulos en la lista de directorios dada por la variable sys.path, que se inicializa desde el directorio que contiene el guion de entrada (o el directorio actual), $PYTHONPATH y el valor por omisi�n dependiente de la instalaci�n. Esto permite que los programas que saben lo que hacen modifiquen o reemplacen el camino de b�squeda de m�dulos. Consulta la secci�n de M�dulos est�ndar que aparece posteriormente.

.�Ficheros Python �Compilados�

Como mejora considerable del tiempo de arranque de programas cortos que utilizan muchos m�dulos est�ndar, si existe un fichero llamado �fiambre.pyc� en el directorio donde se encuentra �fiambre.py�, se supone que contiene una versi�n previamente �compilada a byte� del m�dulo fiambre. La fecha y hora de la versi�n de �fiambre.py� utilizada para generar �fiambre.pyc� se graba en �fiambre.pyc� y no se considera el fichero �.pyc� si no concuerdan.

Normalmente, no hay que hacer nada para generar el fichero �fiambre.pyc�. Siempre que �fiambre.py� se compile sin errores, se hace un intento de escribir la versi�n compilada a �fiambre.pyc�. No se provoca un error si falla el intento. Si por cualquier motivo no se escribe completamente el fichero, el fichero �fiambre.pyc� resultante ser� reconocido como no v�lido y posteriormente ignorado. El contenido del fichero �fiambre.pyc� es independiente de la plataforma, por lo que se puede compartir un directorio de m�dulos entre m�quinas de diferentes arquitecturas.

Consejos para los expertos:

  • Cuando se llama al int�rprete de Python con el indicador -O, se genera c�digo optimizado, que se almacena en ficheros �.pyo�. El optimizador actual no resulta de gran ayuda, s�lo elimina sentencias assert e instrucciones SET_LINENO. Cuando se utiliza -O, todo el c�digo de byte se optimiza. Se ignoran los ficheros .pyc y se compilan los ficheros .py a c�digo byte optimizado.
  • Pasar dos indicadores -O al int�rprete de Python (-OO) hace que el compilador a c�digo byte realice optimizaciones que, en casos poco frecuentes, dan como resultado programas que no funcionan correctamente. Actualmente, s�lo se eliminan las cadenas __doc__ del c�digo byte, lo que da como resultado ficheros �.pyo� m�s compactos. Como hay programas que suponen que estas cadenas est�n disponibles, s�lo se deber�a utilizar esta opci�n con conocimiento de causa.
  • Un programa no se ejecuta m�s r�pido cuando se lee de un fichero �.pyc� o �.pyo� que cuando se lee de un fichero �.py�. La �nica diferencia es el tiempo que tarda en cargarse.
  • Cuando se ejecuta un guion dando su nombre en la l�nea de �rdenes, nunca se escribe el c�digo byte en un fichero �.pyc� o �.pyo�. Por ello, se puede reducir el tiempo de arranque de un guion moviendo la mayor�a del c�digo a un m�dulo y dejando un peque�o arranque que importa el m�dulo. Tambi�n es posible nombrar directamente un fichero �.pyc� o �.pyo� en la l�nea de �rdenes.
  • Es posible tener un m�dulo llamado �fiambre.pyc� (o �fiambre.pyo� si se utiliza -O) sin que exista el fichero �fiambre.py� en el mismo directorio. De este modo se puede distribuir una biblioteca de c�digo de Python dificultando en cierta medida la ingenier�a inversa.
  • El m�dulo compileall puede generar los ficheros �.pyc� (o �.pyo� si se utiliza -O) para todos los m�dulos de un directorio.

.�M�dulos est�ndar

Python viene con una biblioteca de m�dulos est�ndar, descrita en un documento aparte, la Referencia de las bibliotecas (�Referencia de las Bibliotecas� de aqu� en adelante). Algunos m�dulos son internos al int�rprete y proporcionan acceso a las operaciones que no son parte del n�cleo del lenguaje pero se han incluido por eficiencia o para proporcionar acceso a primitivas del sistema operativo, como las llamadas al sistema. El conjunto de dichos m�dulos es una opci�n de configuraci�n. Por ejemplo, el m�dulo amoeba s�lo se proporciona en sistemas que de alg�n modo tienen acceso a primitivas Amoeba. Hay un m�dulo en particular que merece una especial atenci�n, el m�dulo sys, que es siempre interno en cualquier int�rprete Python. Las variables sys.ps1 y sys.ps2 definen las cadenas utilizadas como indicador principal y secundario:

>>> import sys
>>> sys.ps1
�>>> �
>>> sys.ps2
�... �
>>> sys.ps1 = �C> �
C> print ��Puaj!�
�Puaj!
C>

Estas variables s�lo est�n definidas si el int�rprete est� en modo interactivo.

La variable sys.path es una lista de cadenas que determina el camino de b�squeda de m�dulos del int�rprete. Se inicializa a un valor por omisi�n tomado de la variable de entorno $PYTHONPATH o de un valor por omisi�n interno, si $PYTHONPATH no tiene valor. Se puede modificar mediante operaciones de lista est�ndar, por ejemplo:

>>> import sys
>>> sys.path.append(�/ufs/guido/lib/python�)

.�La funci�n dir()

La funci�n interna dir() se utiliza para averiguar qu� nombres define un m�dulo. Devuelve una lista de cadenas ordenada:

>>> import fibo, sys
>>> dir(fibo)
[�__name__�, �fib�, �fib2�]
>>> dir(sys)
[�__name__�, �argv�, �builtin_module_names�, �copyright�, �exit�,
�maxint�, �modules�, �path�, �ps1�, �ps2�, �setprofile�, �settrace�,
�stderr�, �stdin�, �stdout�, �version�]

Sin argumentos, dir() enumera la lista de nombres definidos actualmente (por ti o por el sistema):

>>> a = [1, 2, 3, 4, 5]
>>> import fibo, sys
>>> fib = fibo.fib
>>> dir()
[�__name__�, �a�, �fib�, �fibo�, �sys�]

Observa que enumera todo tipo de nombres: variables, m�dulos, funciones, etc.

dir() no devuelve los nombres de las funciones y variables internas. Si deseas obtener esos nombres, est�n definidos en el m�dulo est�ndar __builtin__:

>>> import __builtin__
>>> dir(__builtin__)
[�AccessError�, �AttributeError�, �ConflictError�, �EOFError�, �IOError�,
�ImportError�, �IndexError�, �KeyError�, �KeyboardInterrupt�,
�MemoryError�, �NameError�, �None�, �OverflowError�, �RuntimeError�,
�SyntaxError�, �SystemError�, �SystemExit�, �TypeError�, �ValueError�,
�ZeroDivisionError�, �__name__�, �abs�, �apply�, �chr�, �cmp�, �coerce�,
�compile�, �dir�, �divmod�, �eval�, �execfile�, �filter�, �float�,
�getattr�, �hasattr�, �hash�, �hex�, �id�, �input�, �int�, �len�, �long�,
�map�, �max�, �min�, �oct�, �open�, �ord�, �pow�, �range�, �raw_input�,
�reduce�, �reload�, �repr�, �round�, �setattr�, �str�, �type�, �xrange�]

.�Paquetes

Los paquetes son un m�todo de estructurar el espacio nominal de m�dulos de Python, mediante el uso de �nombres de m�dulos con punto�. Por ejemplo, el nombre de m�dulo A.B hace referencia a un subm�dulo denominado �B� de un paquete denominado �A�. Del mismo modo que el uso de m�dulos evita que los autores de diferentes m�dulos tengan que preocuparse de los nombres de variables globales de los otros, la utilizaci�n de nombres de m�dulo con puntos evita que los autores de paquetes multi-m�dulo, como NumPy o PIL (la Biblioteca de tratamiento de imagen de Python), tengan que preocuparse de los nombres de los m�dulos ajenos.

Sup�n que deseas dise�ar una colecci�n de m�dulos (un paquete) para tratar de manera uniforme ficheros de sonido y datos de sonido. Existen muchos formatos de fichero de sonido (que se suelen distinguir por la extensi�n, como �.wav�, �.aiff� o �.au�), por lo que podr�as necesitar crear y mantener una colecci�n creciente de m�dulos de conversi�n entre los diferentes formatos. Tambi�n existen muchas operaciones posibles sobre los datos de sonido (tales como mezclar, a�adir eco, ecualizar o generar un efecto artificial de estereofon�a), por lo que, adem�s, estar�as escribiendo una serie de m�dulos interminable para realizar estas operaciones. He aqu� una posible estructura de tu paquete (expresado en t�rminos de sistema de ficheros jer�rquico):

Sonido/ Paquete de nivel superior
    __init__.py         Inicializa el paquete de sonido
    Formatos/           Subpaquete de conversiones de formato de ficheros
        __init__.py
        leerwav.py
        escriwav.py
        leeraiff.py
        escriaiff.py
        leerau.py
        escriau.py
        ...
    Efectos/ Subpaquete de efectos de sonido
        __init__.py
        eco.py
        surround.py
        inverso.py
        ...
    Filtros/ Subpaquete de filtros
        __init__.py
        ecualizador.py
        vocoder.py
        karaoke.py
        ...

Los ficheros �__init__.py� son necesarios para que Python trate los directorios como contenedores de paquetes. Se hace as� para evitar que los directorios con nombres comunes, como �test�, oculten accidentalmente m�dulos v�lidos que aparezcan m�s tarde dentro del camino de b�squeda. En el caso m�s sencillo, �__init__.py� puede ser un fichero vac�o, pero tambi�n puede ejecutar c�digo de inicializaci�n del paquete o actualizar la variable __all__, descrita posteriormente.

Los usuarios del paquete pueden importar m�dulos individuales del paquete, por ejemplo:

import Sonido.Efectos.eco

De este modo se carga el subm�dulo Sonido.Efectos.eco. Hay que hacer referencia a �l por su nombre completo, por ejemplo:

Sonido.Efectos.eco.filtroeco(entrada, salida, retardo=0.7, aten=4)

Un modo alternativo de importar el subm�dulo es:

from Sonido.Efectos import eco

As� tambi�n se carga el subm�dulo eco y se hace disponible sin su prefijo de paquete, por lo que se puede utilizar del siguiente modo:

eco.filtroeco(entrada, salida, retardo=0.7, aten=4)

Y otra variaci�n es importar la funci�n o variable deseada directamente:

from Sonido.Efectos.eco import filtroeco

De nuevo, se carga el subm�dulo eco, pero se hace la funci�n filtroeco disponible directamente:

filtroeco(entrada, salida, retardo=0.7, aten=4)

Observa que al utilizar from paquete import elemento, el elemento puede ser tanto un subm�dulo (o subpaquete) del paquete como cualquier otro nombre definido por el paquete, como una funci�n, clase o variable. La sentencia import comprueba primero si el elemento est� definido en el paquete. Si no, asume que es un m�dulo e intenta cargarlo. Si no lo consigue, se provoca una excepci�n ImportError.

Sin embargo, cuando se utiliza la sintaxis import elemento.subelemento.subsubelemento, cada elemento menos el �ltimo debe ser un paquete. El �ltimo elemento puede ser un m�dulo o un paquete, pero no una clase, funci�n o variable definida en el nivel superior.

Importar * de un paquete

Y �qu� ocurre cuando el usuario escribe from Sonido.Efectos import *? En teor�a, deber�a rastrearse el sistema para encontrar qu� subm�dulos existen en el paquete e importarlos todos. Por desgracia, esta operaci�n no funciona muy bien en las plataformas Windows y Mac, en las que el sistema de ficheros no tiene una idea muy precisa de las may�sculas de un fichero. En estas plataformas, no hay un modo garantizado de conocer si un fichero �ECO.PY� deber�a ser importado como eco, Eco o ECO (por ejemplo, Windows 95 tiene la molesta costumbre de mostrar todos los nombres de fichero con la primera letra en may�scula). La restricci�n de nombres de fichero DOS (8+3) a�ade otro problema para los nombres de m�dulo largos.

La �nica soluci�n es que el autor del paquete proporcione un �ndice expl�cito del paquete. La sentencia import utiliza la siguiente convenci�n: Si el c�digo del �__init__.py� de un paquete define una lista llamada __all__, se considera que es la lista de nombres de m�dulos que se deben importar cuando se encuentre from paquete import *. Depende del autor del paquete mantener la lista actualizada cuando se libere una nueva versi�n del paquete. Los autores del paquete pueden decidir no mantenerlo, si no es �til importar * del paquete. Por ejemplo, el fichero �Sonido/Efectos/__init__.py� podr�a contener el siguiente c�digo:

__all__ = ["eco", "surround", "inverso"]

Esto significar�a que from Sonido.Efectos import * importar�a los tres subm�dulos mencionados del paquete Sonido.

Si __all__ no est� definido, la sentencia from Sonido.Efectos import * no importa todos los m�dulos del subpaquete Sonido.Efectos al espacio nominal actual. S�lo se asegura de que el paquete Sonido.Efectos ha sido importado (ejecutando posiblemente su c�digo de inicializaci�n), �__init__.py�) y luego importa cualesquiera nombres definidos en el paquete. Esto incluye cualquier nombre definido (y subm�dulos cargados expl�citamente) por �__init__.py�. Tambi�n incluye cualquier subm�dulo del paquete expl�citamente importado por sentencias import anteriores, por ejemplo:

import Sonido.Efectos.eco
import Sonido.Efectos.surround
from Sonido.Efectos import *

En este ejemplo, los m�dulos eco y surround se importan al espacio nominal vigente porque est�n definidos en el paquete Sonido.Efectos cuando se ejecuta la sentencia from...import (esto tambi�n funciona si est� definido __all__).

Observa que en general se debe evitar importar * de un m�dulo o paquete, ya que suele dar como resultado c�digo poco legible. Sin embargo, se puede usar para evitar teclear en exceso en sesiones interactivas y cuando ciertos m�dulos est�n dise�ados para exportar s�lo nombres que cumplan ciertas reglas.

Recuerda, �no hay nada incorrecto en utilizar from Paquete import subm�dulo_concreto! De hecho, es la notaci�n recomendada salvo que el m�dulo que importa necesite usar subm�dulos del mismo nombre de diferentes paquetes.

Referencias internas al paquete

Es com�n que los subm�dulos necesiten hacerse referencias cruzadas. Por ejemplo, el m�dulo surround podr�a utilizar el m�dulo eco. De hecho, tales referencias son tan comunes que la sentencia import busca antes en el paquete contenedor que en el camino de b�squeda de m�dulos est�ndar. Por ello, basta con que el m�dulo surround use import eco o from eco import filtroeco. Si el m�dulo importado no se encuentra en el paquete actual (el paquete del que el m�dulo actual es subm�dulo), la sentencia import busca un m�dulo de nivel superior con el nombre dado.

Cuando se estructuran los paquetes en subpaquetes (como el paquete Sonido del ejemplo), no hay un atajo para referirse a los subm�dulos de los paquetes hermanos y se ha de utilizar el nombre completo del subpaquete. Por ejemplo, si el m�dulo Sonido.Filtros.vocoder necesita utilizar el m�dulo eco del paquete Sonido.Efectos, debe utilizar from Sonido.Efectos import eco.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR