Página inmutable History Adjuntos

Cursos/Principiantes/Parte4

Nombre de la página: Cursos / Principiantes / Parte4



Módulos y paquetes

Los módulos y paquetes proveen la función de encapsular funcionalidad a un solo archivo (o conjuntos de archivos), hasta el momento todos los ejemplos que hemos visto han estado en solo un archivo, en ejemplos mas reales muchas veces se distribuye la funcionalidad a través de módulos y paquetes, de esta forma se ceden responsabilidades a un modulo en particular y lo cual permite evitar el que se duplique el trabajo.

Cada archivo con terminación .py se le considera un módulo en python.

Cada directorio que contenga un archivo de nombre __init__.py se le considera un paquete, dentro de ese directorio todo módulo de python (archivos con terminación .py) se le considera un miembro del paquete que lo contiene.

Al importarlo se ejecuta el contenido del archivo __init__.py.

Además de __init__.py existe otro nombre de archivo reservado __main__.py, el cual se ejecuta si se trata de ejecutar el paquete como si fuera un modulo, algo así como se hace usualmente:

   python modulo.py

En un paquete se hace:

  python -m paquete

donde paquete tiene la siguiente estructura:

    paquete/__init__.py
            __main__.py
            modulo1.py
            modulo2.py   

PYTHONPATH es la variable de entorno que indica los directorios donde se va a buscar los módulos.

La forma de como usar un modulo/paquete es a través de la palabra reservada

    import 

La cual tiene formas diferentes de usarse siendo las mas básica:

import MODULO

ó

import PAQUETE

Una vez que se ha ejecutado la expresión se asigna una variable con el nombre del módulo el cual se convierte el la puerta hacia la funcionalidad del mismo, llegamos a su contenido a través del operador punto "."

Por ejemplo:

  MODULO.VARIABLE
  MODULO.FUNCION()

En los ejemplos que menciono uso mayúsculas solo para demostrar lo que se supone debe ser eso, python distingue entre mayúsculas y minúsculas así que es es importante usar la capitalización correcta respecto al nombre del modulo/paquete.

Como buena practica se considera que los módulos y paquete deben de estar en minúsculas.

Una vez que se importa un modulo se dice que el modulo esta en el "Namespace", o en caso de ser importaciones parciales solo las propiedades que se importan están en el "Namespace".

El concepto de "Namespace" es fundamental en proyectos de software de mediano tamaño, permiten mantener orden y proveen eficiencia al solo tener al alcance lo que realmente va a ser usado al nivel de ese módulo en particular.

Una vez que se ha importado un modulo o paquete todos los archivos que se usaron para construir el modulo se "compilan a bytecode", el cual es una representación del texto plano que constituye a los archivos normales (.py) pero facilita su interpretación a python.

En python2 crear archivos con terminación.pyc en python3 crea un directorio __pycache__ que contiene los .pyc, para fines prácticos estos archivos no son relevantes para fines de funcionalidad, python siempre verifica que este compilada la ultima versión en el .pyc en caso contrario lo vuelve a generar.

No se debe de mantener en un sistema de control de versiones los .pyc, se pueden borrar sin peligro alguno (siempre y cuando aún tengan el `.py).

   1 def importar_modulo_forma_uno():
   2     """
   3     Importación básica (recomendada)
   4     """
   5     import operadores
   6     
   7 
   8 def importar_modulo_forma_dos():
   9     """
  10     Importación básica con asignación de nombre especial 
  11     """
  12     import operadores as opr
  13 
  14 def importar_modulo_forma_tres():
  15     """
  16     Importación parcial
  17     """
  18     from operadores import suma, resta, multiplicacion, division
  19 
  20 def importar_modulo_forma_cuato():
  21     """
  22     Importación parcial con asignación de nombre.
  23     """
  24     import operadores.suma as suma
  25 
  26     
  27 def importar_modulo_forma_cinco():    
  28     """
  29     Importación de todo el contenido del modulo sin usar
  30     sin asignar la variable operadores.
  31     """
  32     from operadores import *
  33     # ahora se pueden usar suma, resta, division y multiplicacion
  34     # como si se definieran en el mismo archivo.
  35 
  36     
  37 # Las siguientes funciones usa import, de forma relativa.
  38 # Usualmente no son recomendadas.
  39     
  40 def importacion_relativa_uno():
  41     """Importación relativa"""
  42     from .operadores import suma
  43 
  44 def importacion_relativa_dos():
  45     """Importación relativa """
  46     from . import bases
  47 
  48 def importacion_relativa_tres():
  49     """Importación relativa al paquete que contiene al modulo,
  50     basicamente te permite acceder a modulos en un nivel anterior.
  51     """
  52     from .. import bases
  53 
  54 
  55 def ejemplo_mezclado():
  56     """
  57     Es muy inusual que se encuentren este estilo de importación
  58     de módulos, pero la idea es que se puede tener cualquier cantidad
  59     separados por comas, además de poder tener saltos de linea
  60     siempre y cuando estén dentro de paréntesis
  61     """
  62     from operadores import (
  63         suma as s,
  64         resta as r,
  65         multiplicacion as m,
  66         division as d
  67     )
  68     
  69     
  70 
  71 """
  72 En general la importación básica es recomendada ya que indica
  73 de donde proviene lo que se importa y aporta contexto
  74 sobre lo que refiere al funcionalidad a la que se esta accediendo.
  75 """
  76 
  77 """
  78 Dado que todos los archivos en python se consideran módulos, existe
  79 una forma de poder detectar cuando se quiere ejecutar el archivo o si se esta importando como modulo, no es común ver la siguiente estructura al final de un archivo de python.
  80 """
  81 
  82 def main():
  83     """
  84     Ejecuta cosas que vayan a tener efectos secundarios indeseados al importar
  85     """
  86 
  87 # Se incluye un `if` para verificar el contendio
  88 # de la variable especial __name__, la cual
  89 # tiene el nombre del modulo en una cadena cuando se importa
  90 # en caso de que no se importe, entonces tiene como valor
  91 # '__main__'
  92 if __name__ == '__main__':
  93     main()
  94 
  95 ##   ____                _                                          _ _   _
  96 ##  / ___|_ __ __ _  ___(_) __ _ ___   _ __   ___  _ __    __ _ ___(_) |_(_)_ __
  97 ## | |  _| '__/ _` |/ __| |/ _` / __| | '_ \ / _ \| '__|  / _` / __| | __| | '__|
  98 ## | |_| | | | (_| | (__| | (_| \__ \ | |_) | (_) | |    | (_| \__ \ | |_| | |
  99 ##  \____|_|  \__,_|\___|_|\__,_|___/ | .__/ \___/|_|     \__,_|___/_|\__|_|_|
 100 ##                                    |_|