08 - Curso de Python - Modulos
Cualquier duda suelo atender en este foro de python
Todo el código de este curso de Python gratuito está en github https://github.com/chuidiang/chuidiang-ejemplos/tree/master/PYTHON/curso-python. En línea comandos python tienes como arrancar la consola de comandos de python por si quieres ir probando lo relativo a variables y tipos de datos en python.
Anterior: 07 - Curso de Python - Entradas y Salidas Standard -- Índice: Curso de Python -- Siguiente: 09 - Curso de Python - Clases en Python.
Módulos en Python[editar]
Como vimos al principio del curso, nuestro programa python es un fichero de texto de extensión .py. Con el comando python fichero.py
podemos ejecutarlo. Esto está bien para programas sencillos. Pero si el programa es muy grande, un solo fichero puede ser inmanejable para meter ahí todo el código. Si el programa es grande, deberíamos partir el código en varios ficheros de forma que cada fichero contenga código más o menos relacionado con lo que hay en el fichero. Y un fichero principal donde comienza nuestro programa.
Por ejemplo, imagina que quieres hacer un programa que lleve una contabilidad, que guarde en base de datos tus cuentas, que tenga una interface de usuario y que haga ciertos cálculos con tus cuentas. Podríamos tener un fichero contabilidad_base_datos.py con funciones relativas a guardar y consultar nuestras cuentas en base de datos, un fichero contabilidad_interface_usuario.py con todo lo relativo a la interface de usuario, un fichero contabilidad_cuentas.py con todos las funciones de cálculos que queramos y finalmente un fichero contabilidad.py que sea el que arranquemos y vaya llamando a los otros según se necesite.
Cada fichero .py con una funcionalidad concreta se conoce en python como modulo. Veamos ejemplos de cómo hacerlos.
Creamos un módulo[editar]
Como hemos dicho, un módulo no es más que un fichero .py con código. Hagamos uno con cuatro funciones: suma()
, resta()
, multiplica()
y divide()
. En un ejemplo real no merece la pena hacer esto tan tonto, ya que python tiene operadores para echar estas cuentas, pero valga de ejemplo. Creamos un fichero calculadora.py
y metemos la definición de las cuatro funciones
def suma(a,b):
return a+b
def resta(a,b):
return a-b
def multiplica(a,b):
return a*b
def divide(a,b):
return a/b
Listo, ya tenemos el módulo creado.
Uso del módulo[editar]
Importar el módulo[editar]
Para usar este módulo, vete con la ventana de comandos de windows / terminal de linux al directorio donde hayas creado este fichero y abre el interprete de comandos de python. Una vez ahí, puedes escribir lo siguiente para usar el módulo.
>>> import calculadora >>> calculadora.suma(1,2) 3
Básicamente hemos puesto import calculadora
, siendo calculadora el nombre del fichero, pero sin la extensión. A partir de ahí podemos usar las funciones de ese fichero/módulo poniendo delante calculadora.
. Es decir, tendríamos disponible calculadora.suma()
, calculadora.resta()
, calculadora.multiplica()
y calculadora.divide()
Importar partes del módulo[editar]
Hay una variante de la sintaxis del módulo que consiste en indicar qué funciones concretas queremos importar. Por ejemplo
>>> from calculadora import suma >>> suma(1,2) 3 >>> divide(1,2) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'divide' is not defined >>> calculadora.divide(1,2) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'calculadora' is not defined
haciendo un from modulo import funcion
, solo importamos esa función. Y hay un detalle adicional, ya no necesitamos poner el prefijo calculadora
para usar la función. En el ejemplo, fíjate que después del from ... import ...
usamos suma()
sin ningún tipo de prefijo y funciona. Intentamos usar divide()
tanto sin prefijo como con prefijo y no funciona.
Podemos importar varias funciones a la vez
>>> from calculadora import suma, resta >>> suma(1,2) 3 >>> resta(1,2) -1
o todas de golpe
>>> from calculadora import * >>> suma(1,2) 3 >>> divide(1,2) 0.5 >>>
La única diferencia de este último método frente al anterior comentado import calculadora
es la necesidad o no de usar el prefijo calculadora.
antes de llamar a las funciones.
Cambio de nombre de módulos y funciones[editar]
Al importar podemos cambiar el nombre del módulo y de las funciones, de forma que si hay varios módulos que se llamen igual o definan las mismas funciones, podamos eviar el conflicto. La siguiente variante de import
cambia el nombre del módulo.
>>> import calculadora as calcu >>> calcu.suma(1,2) 3 >>> calculadora.suma(1,2) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'calculadora' is not defined
Importamos calculadora con el nombre calcu. Así que podemos usar calcu.suma()
, pero no calculadora.suma()
.
Lo mismo si importamos funciones sueltas
>>> from calculadora import suma as sumador >>> suma(1,2) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'suma' is not defined. Did you mean: 'sum'? >>> sumador(1,2) 3
En vez de suma()
, le damos el nombre sumador()
y con ese nombre la podemos usar.
Variables en el módulo[editar]
Todo lo que hemos dicho para crear e importar funciones de módulo, valdría también para variables. Imagina que definimos el siguiente módulo matematicas.py
PI = 3.1416
e = 2.7183
Podemos ahora jugar con esto. Abre el interprete de comandos de python en el directorio donde esté este fichero
>>> import matematicas >>> matematicas.PI 3.1416 >>> from matematicas import PI >>> PI 3.1416
Espacios de nombres[editar]
Como estamos viendo, cada modulo puede definir sus variables y funciones. Cuando importamos dichos módulos no hay conflictos de nombres, aunque las funciones o variables se llamen igual porque cada variable y función tiene su propio espacio de nombres identificado por el nombre del módulo. Si tienes la función suma()
en el módulo calculadora.py y matematicas.py, pueden coexistir ya que a una se le llama calculadora.suma()
y al otro matematicas.suma()
. Siempre, claro, que los módulos se llamen distinto y no cambies el nombre con mala intención para que coincida.
Inicialización de un módulo[editar]
Si en módulo además de funciones ponemos código ejecutable, ese código se ejecutará la primera vez que se importe el módulo, no el resto de veces. Esto es útil si por el motivo que sea necesitamos que se ejecute algo de incialización del módulo antes de usarlo. Veamos un ejemplo. Crea un fichero module_init.py
en un directorio con este contenido
print ('Se inicia modulo de python module_init')
def module_init():
print('Soy la funcion python de module_init')
Ahora, con el interprete de comandos de python abierto en el mismo directorio donde esté ese fichero, escribe
>>> import module_init Se inicia modulo de python module_init >>> module_init.module_init() Soy la funcion python de module_init >>> import module_init >>>
Ves que al hacer el import
, sale en pantalla el texto "Se inicia el modulo de python module_init". Luego podemos usar la función ahí definida. Si hacemos un segundo import
, ya no se ejecuta el print()
que saca por pantalla "Se inicia modulo module_init".
paquetes[editar]
Si queremos más organización todavía, podemos poner una estructura de directorios de forma que cada uno tenga módulos relacionados. Esta organización de módulos por directorios se conoce como "paquetes". Por ejemplo, crea un directorio "ordenadores". Dentro de él dos directorios, uno que se llame "portatiles" y el otro "sobremesa". Dentro de cada uno de ellos un fichero lenovo.py
con el siguiente contenido
print ('Inicializando portatil lenovo')
def presentate():
print ('Soy el portatil lenovo')
print ('Inicializando sobremesa lenovo')
def presentate():
print ('Soy el sobremesa lenovo')
Te dejo que adivines en que directorio va cada uno de estos ficheros. Adicionalmente, en el directorio "ordenadores" debes crear un fichero de nombre __init__.py
. El nombre debe ser ese obligatoriamente y el fichero puede estar vacío o contener código que se ejecute la primera vez que se importe el paquete. Ese fichero sirve para que pyhton identifique ese directorio "ordenadores" como el directorio raíz de un paquete que va a tener varios subdirectorios y módulos, no como un directorio normal. En nuestro caso podemos el siguiente código en ese fichero
print('Inicializando paquete ordenadores')
así veremos que se importa. Una vez tengas todo, abre el interprete de python en el directorio padre de "ordenadores", es decir, no donde está el fichero __init__.py
, sino en el superior. Una vez abierto, puedes ejecutar lo siguiente
>>> import ordenadores.portatiles.lenovo Inicializando paquete ordenadores Inicializando portatil lenovo >>> ordenadores.portatiles.lenovo.presentate() Soy el portatil lenovo >>> import ordenadores.sobremesa.lenovo Inicializando sobremesa lenovo >>> ordenadores.sobremesa.lenovo.presentate() Soy el sobremesa lenovo
Puedes hacer el import
poniendo todo el path desde "ordenadores" hasta llegar al módulo que te interesa, pero separando los directorios con punto en vez de con \ (o con / en linux). Cuando importas el primero ordenadores.portatiles.lenovo
ves el código de inicialización tanto del paquete como el módulo lenovo dentro de portátiles. Luego ya podemos usar lo que haya el módulo siempre poniendo como prefijo todo el camino del paquete.
Idem con los de sobremesa. Únicamente fíjate que el paquete ya no se inicializa, puesto que ya se inicializó antes.
Y por supuesto, puedes jugar en el import
con from
y as
para importar cosas concretas, no tener que usar los prefijos y cambiar los nombres.
El main en python[editar]
Cuando nuestro programa se compone de varios ficheros .py, cada uno con definiciones de funciones, código, variables, etc, suele haber uno de esos ficheros que es el fichero principal, el que arrancamos con el comando python fichero_principal.py
. Ese se encargará de ir importando a los demás módulos.
Vamos a imaginar algo un poco más complejo. Imagina que haces un programa calculadora.py
. Ahí defines las funciones aritméticas que ya hemos visto: suma, resta, division y multiplicación. Y en el mismo fichero calculadora.py
pones código para que le pida al usuario números, operaciones y vaya echando las cuentas llamando a las funciones. Por simplificarlo, pedimos dos números a piñón fijo para sumarlos. Algo como esto
def suma(a,b):
return a+b
def resta(a,b):
return a-b
def multiplica(a,b):
return a*b
def divide(a,b):
return a/b
a = input ('Dime el primer sumando ')
b = input ('Dime el segundo sumando ')
print ('La suma es ', suma(int(a),int(b)))
Hemos definido las funciones y hemos puesto código para que nos pida dos números y los sume. Hasta aquí todo bien. Pero imagina ahora que queremos seguir teniendo nuestra calculadora, pero queremos aprovechar el fichero como módulo de otro programa y así aprovechar las funciones ahí definidas. Si recuerdas, cuando hacemos un import
de un módulo, podemos usar las funciones, pero también se ejecuta el código de ese módulo, en este caso, el pedir dos números y sacar la suma. Y seguramente eso no nos interesa en nuestro programa. ¿Cómo lo evitamos?. Pues debemos poner ese código en una función. La función puede llamarse como quieras, pero el nombre estándar que se suele poner es main()
. De esta forma, si en un módulo vemos una función de nombre main()
, sabremos que ese módulo puede usarse como un programa principal aparte de usarse como un módulo para importar. Quedaría así
def main():
a = input ('Dime el primer sumando ')
b = input ('Dime el segundo sumando ')
print ('La suma es ', suma(int(a),int(b)))
Si ahora ejecutamos el fichero con python calculadora.py
no hará nada. Hemos metido el código principal en una función main()
, pero python no la ejecuta. ¿Como conseguimos que se ejecute sólo si lo arrancamos con python calculadora.py
pero no sí lo importamos desde otro módulo?. Python en cada módulo define una variable de nombre __name__
. Si arrancamos el fichero con el comando python calculadora.py
esta variable valdrá siempre __main__
. Si lo importamos, esta variable valdrá calculadora
, es decir, el nombre del módulo.
Si añadimos print(__name__)
al final de nuestro fichero calculadora.py
podemos ver esto con las siguientes ejecuciones
Ejecutando desde ventana de comandos de windows/terminal de linux
C:\> python calculadora.py __main__
Haciendo un import desde el intérprete de comandos de python
>>> import calculadora calculadora
Pues bien, podemos aprovechar esto para poner una condicion (un if
) y ejecutar la función main()
sólo si __name__ == '__main__'
, tal que así
def suma(a,b):
return a+b
def resta(a,b):
return a-b
def multiplica(a,b):
return a*b
def divide(a,b):
return a/b
def main():
a = input ('Dime el primer sumando ')
b = input ('Dime el segundo sumando ')
print ('La suma es ', suma(int(a),int(b)))
if (__name__ == '__main__'):
main()
Listo, si ejecutamos con python calculadora.py
se ejecutará la función main()
y nos pedirá números para sumar. Si hacemos un import
desde otro fichero python, importaremos las funciones pero no se ejecutará nada. Esto nos permite tener todos los módulos que queramos con funciones que podemos reutilizar en otros lados, pero a su vez esos módulos pueden ser programas independientes que hacen cosas sólo si se los llama directamente y no con un import
.
Búsqueda de módulos[editar]
Python busca los módulos (ficheros) en los siguientes directorios, en este orden:
- Directorio actual de ejecución. Por eso era importante que abrieras el intéprete de comandos en el directorio donde estaba el fichero calculadora.py
- Donde diga la variable de entorno PYTHONPATH. Vemos ahora un ejemplo.
- En el directorio lib de la instalación de python. Vemos más detalles ahora.
PYTHONPATH[editar]
Para ver como funciona PYTHONPATH, cierra el interprete de comandos de python con quit()
. Vete a otro directorio cualquiera en la ventana de comandos de windows / terminal de linxu y define la variable PYTHONPATH y dale el valor del directorio donde esté calculadora.py. En el caso de windows sería así
set PYTHONPATH=C:\Users\fjabe\Proyectos\chuidiang-ejemplos\PYTHON\curso-python\08-Modulos
El directorio es el mio concreto. Tendrás que poner el que tengas tú. Ahora, estando ya en otro directorio que no sea ese, abre otra vez el interprete de comandos de python y vuelve a ejecutar el código del apartado "Uso del Módulo". Verás que funciona correctamente.
Módulos del sistema[editar]
La última ubicación a buscar es el directorio lib de donde esté instalado python. Si vas a ese directorio verás que hay muchos ficheros .py. Te pego una captura de mi directorio lib
Archivo:Lib-python.PNG
Todos esos son módulos que viene con python y que puedes usar en tu código. Por ejemplo, hay un módulo os.py
con fuciones útiles del sistema operativo, como la de manejo de los ficheros. Mira el siguiente código
>>> import os >>> os.listdir() ['01-Descarga-Y-Hola-Mundo', '02-Variables', '03-Listas-Diccionarios-Arrays', '04-Condiciones_Y_Bucles', '08-Modulos']
Tras importar os
, podemos usar sus funciones y en concreto os.listdir()
, que nos da una lista de ficheros/directorios en el directorio actual. Admite como parámetro un directorio. De esta forma nos daría el listado de ficheros en ese directorio concreto.
>>> import os >>> os.listdir('C:\\') ['$Recycle.Bin', '$WinREAgent', 'Archivos de programa', 'Boot', 'bootmgr', 'Config.Msi', 'Documents and Settings', 'Drivers', 'DumpStack.log.tmp', 'hiberfil.sys', 'Intel', 'logs', 'OneDriveTemp', 'pagefile.sys', 'PerfLogs', 'Program Files', 'Program Files (x86)', 'ProgramData', 'Recovery', 'swapfile.sys', 'System Volume Information', 'UserGuidePDF', 'Users', 'Windows']
Fíjate que en el parámetro hemos puesto \\ dos veces. Esto se debe a que en python las cadenas de caracteres pueden contener caracteres especiales que habitualmente empiezan con \. Por ejemplo, \n es un retorno de carro. Fijate en el siguiente código
>>> print('hola\ntu\n.') hola tu .
Cada \n que hemos puesto lo interpreta como empezar una línea nueva. Por eso, si quieres que saque una \, debes escribir en la cadena doble \\. Es la forma de decirle a python que queremos una \ y que no interprete lo que hay detrás como un carácter especial.
Anterior: 07 - Curso de Python - Entradas y Salidas Standard -- Índice: Curso de Python -- Siguiente: 09 - Curso de Python - Clases en Python.