Subsecciones


6. Módulos

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 de 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


6.1 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 parte6.1.

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, nombreMod.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 (_).


6.1.1 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. Obsérvese que, como el directorio que contiene el guion bajo ejecución está en el camino de búsqueda de módulos, es importante que el módulo no tenga el mismo nombre que un módulo estándar, o Python lo intentará cargar el guion como módulo cuando se importe el módulo. Normalmente, esto provocará errores. Ver la sección 6.2, ``Módulos estándar,'' para obtener más información.

6.1.2 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:


6.2 Módulos estándar

Python viene con una biblioteca de módulos estándar, descrita en un documento aparte, la Referencia de las bibliotecas. 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 que también depende de la plataforma subyacente. 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 de 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')


6.3 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)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', 
'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',
'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 
'displayhook', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix',
'executable', 'exit', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 
'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'hexversion', 
'last_traceback', 'last_type', 'last_value', 'maxint', 'maxunicode', 
'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 
'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags', 'setprofile', 
'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'version', 
'version_info', 'warnoptions']

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()
['__builtins__','__doc__','__file__','__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__)
['ArithmeticError', 'AssertionError', 'AttributeError', 'DeprecationWarning',
 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
 'FloatingPointError', 'FutureWarning', 'IOError', 'ImportError',
 'IndentationError', 'IndexError', 'KeyError', 'KeyboardInterrupt',
 'LookupError', 'MemoryError', 'NameError', 'None', 'NotImplemented',
 'NotImplementedError', 'OSError', 'OverflowError', 'OverflowWarning',
 'PendingDeprecationWarning', 'ReferenceError', 'RuntimeError',
 'RuntimeWarning', 'StandardError', 'StopIteration', 'SyntaxError',
 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'True',
 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError',
 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError',
 'UserWarning', 'ValueError', 'Warning', 'WindowsError',
 'ZeroDivisionError', '_', '__debug__', '__doc__', '__import__',
 '__name__', 'abs', 'apply', 'basestring', 'bool', 'buffer',
 'callable', 'chr', 'classmethod', 'cmp', 'coerce', 'compile',
 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod',
 'enumerate', 'eval', 'execfile', 'exit', 'file', 'filter', 'float',
 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex',
 'id', 'input', 'int', 'intern', 'isinstance', 'issubclass', 'iter',
 'len', 'license', 'list', 'locals', 'long', 'map', 'max', 'min',
 'object', 'oct', 'open', 'ord', 'pow', 'property', 'quit', 'range',
 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set',
 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super',
 'tuple', 'type', 'unichr', 'unicode', 'vars', 'xrange', 'zip']


6.4 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
              ...

Al importar el paquete, Python rastrea los directorios de sys.path buscando por el subdirectorio de paquetes.

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:

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.


6.4.1 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 el código de inicialización de __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. Mira este código:

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.

6.4.2 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.

6.4.3 Paquetes en directorios múltiples

Los paquetes disponen de un atributo especial más, __path__. Este atributo se inicializa con una lista que contiene el nombre del directorio que tiene el __init__.py del paquete antes de que el código de ese fichero se ejecute. Esta variable se puede modificar; hacerlo afecta a futuras búsquedas de módulos y subpaquetes contenidos en el paquete.

A pesar de que no se suele necesitar esta característica, se puede usar para extender el juego de módulos que se encuentran en un paquete.



Notas al pie

... parte6.1
En realidad, las definiciones de funciones también son `sentencias' que se ejecutan. La ejecución introduce el nombre de la función en la tabla de símbolos global.
Consultar en Acerca de este documento... información para sugerir cambios.