Son archivos de texto que contienen sentencias.
Los módulos son procesados con el uso de 3 sentencias principales:
import
Permite a un cliente importar un módulo como un todo
from
Permite obtener algo particular de un módulo.
imp.reload
Provee una forma de recargar un modulo sin reiniciar python.
Por que usar Modulos?
- Proveen una forma facil de organizar componentes dentro de un sistema sirivendo como un paquete de variables auto-contenidas conocido como namespaces (espacio de nombres).
- Todos los nombres definidos en el nivel superior de un archivo de módulo se convierten en atributos del objeto módulo importado.
- Los módulos permiten vincular archivos individuales en un sistema de programa más amplio.
Roles:
- Reuso de código
- Partionado del namespace del sistema.
- Implementar servicios compartidos o de datos.
Arquitectura de programa en Python:
La manera como se divide un programa en partes (módulos) :
- Un programa consiste de multiples archivos de texto conteniendo sentencias:
- Un principal (nivel alto, script), complementado con cero o mas archivos suplementarios conocido como módulos.
- Script Principal: contiene el flujo principal, con el ke se lanza la aplicación.
- Módulos: Librerias de herramientas que apoyan al script principal.
- Módulos no hacen nada cuando se ejecutan.
Imports y Atributos:
Supongamos que b.py define una función llamada spam para uso externo. b.py contendra una sentencia def para generar la función:
def spam(text):
print text, 'spam'
Ahora suponga que a.py quiera usar spam:
import b
b.spam('CualQuier Cosa')
$ python2.7 a.py
Módulos de la Librería Estandar:
Python automaticamente viene con una larga colección de módulos de utilidades conocidos como la Librería Estándar (más de 200 módulos), contiene soporte independiente de la plataforma para tareas comunes de programación, interfaces del sistema operativo, persistencia de objetos, concordancia en patrones de texto, redes e internet, construcción GUI, y mas.
Consulte el manual de referencia de la Libreria Estandar Python (via IDLE, http://www.python.org)
Cómo funciona la importación:
Operaciones en tiempo de ejecución que realizan tres distintos pasos la primera vez que un programa importe un archivo dado:
1. Encontrar el archivo módulo (usando el modulo de search path)
2. Compilarlo a byte code (Si es necesario)
3. Ejecutar el código (byte-code) del modulo para construir los objetos que define (de arriba a abajo).
Como se busca un módulo (Search Path):
El sistema de búsqueda de módulo esta compuesto de la concatenación de ruta, vistas en:
1. El directorio "home" del programa.
2. Entorno PYTHONPATH (orden de izq. a der.)
3. Directorios de Librería Estándar (No necesitan agregarse al PYTHONPATH).
4. Contenido de cualquier archivo .pth (ubique un archivo myconfig.pth en el nivel mas alto del directorio de instalación de Python), o en el subdirectorio site-packages agregando cada directorio listado en cada linea del archivo.
Configurando el Search Path:
Windows:
Panel de Control ajustar PYTHONPATH: c:\pycode\utilidades;d:\pycode\package1
o
Crear archivo de texto: C:\Python30\pydirs.pth
c:\pycode\utilidades
d:\pycode\package1
Lo anterior es análogo a cualquier otra plataforma.
La lista sys.path
Realmente sys.path, es el search path de modulos. Visualiza la lista completa de path que Python usa para buscar:
>>> import sys
>>> sys.path
['', '/usr/lib/python27.zip', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/lib/python2.7/site-packages']
1. Verifica el search path que haya hecho.
2. Provee la forma para los scripts de medir sus search paths manualmente. Si modifca la lista, puede modificar el search path para todos los imports futuros.
Ejemplo, cambiando el sys.path desde programa:
>>> sys.path.append(r'C:\mydir')
>>> sys.path
['', 'C:\\PP3rdEd\\Examples', ...more deleted..., 'C:\\mydir']
Tabla de modulos cargados:
Es un diccionario tipo name:module que resulta de sys.modules:
>>> sys.modules
{'copy_reg': <module 'copy_reg' from '/usr/lib/python2.7/copy_reg.py'>, 'sre_compile': <module 'sre_compile' from '/usr/lib/python2.7/sre_compile.py'>, '_sre': <module '_sre' (built-in)>, 'encodings': <module 'encodings' from '/usr/lib/python2.7/encodings/__init__.py'>, 'site': <module 'site' from '/usr/lib/python2.7/site.py'>, '__builtin__': <module '__builtin__' (built-in)>,...
>>> sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings', 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', '_warnings', 'genericpath', 'stat', 'zipimport', 'encodings.__builtin__', 'warnings', 'UserDict', 'encodings.utf_8', 'sys', 'codecs', 'readline', 'os.path', 'signal', 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']
Preferencias de archivo de modulo a cargar:
import b
buscará:
Codigo fuente b.py
byte code b.pyc
Un directorio llamado b, (importar paquetes)
Un modulo extensión precompilado (Hecho en C/C++ y dinamicamente enlazado, b.so (linux), b.pyd o b.dll (cygwin/windows)
Un modulo incorporado linkeado estaticamente dentro de python.
Un fichero zip automaticamente extraido cuando se importe.
Una clase Java (Jython)
Un componente .NET (IronPython)
distutils: distribuir software de 3eras partes:
Extensiones Python de 3eras partes usan comunmente la herramienta distutils en la libreria standar para instalarles. vienen con un script setup.py el cual es el ke instala.
Creando un Módulo:
Se usa un editor de texto para escribir codigo Python y guardelo con la extensión .py
Cuando se importa un modulo, Python mapea el nombre interno del módulo a un archivo externo agregandolo al frente.
Ejemplo:
modulo1.py
def printer(x): #atributo de módulo
print(x)
Usando un Módulo:
con las sentencias import o from se utiliza un modulo como un todo o copiar parte de este.
Sentencia import:
#obtener el modulo como un todo:
>>> import modulo1
# acceso a los atributos/nombres
>>> modulo1.printer('Hello world')
Hello world!
Sentencia from:
Permite copar nombres directamente al script sin cargar todo el modulo:
>>> from modulo1 import printer
>>> printer('Hello world!')
Hello world
Sentencia from *:
Usando * se obtiene copia de todos los nombres asignados en el "top level" del modulo.
>>> from modulo1 import *
>>> printer('Hello world')
Nota: Python 3.x permite sentencia from * solo en el alto nivel del archivo módulo y no dentro de función.- Python 2.x lo permite en ambos casos.
- import asigna un objeto modulo entero a un nombre sencillo.
- from asigna uno o más nombres a objetos del mismo nombre en otro modulo.
nombres copiados con un from se convierte en referencias a objetos compartidos, (cambiar un objeto traido de caracter mutable puede cambiar luego en el modulo importado). Ejemplo:
small.py:
x = 1
y = [1, 2]
$ python2.7
>>> from small import x, y #copia dos nombres
>>> x = 42 # cambia a x localmente
>>> y[0] = 42 # cambia elemento mutable ahi mismo
>>> x
42
>>> y
[42, 2]
x es no es un objeto mutable compartido, y si lo es.
>>> import small
>>> small.x
1
>>> small.y
[42, 2]
Nota: Evite usar nombres de variables iguales e invocarlas con from! Genera confusión cambiar variables de otros módulos.
Algunos usuarios recomiendan usar mejor import en vez de from la mayor parte del tiempo, pero es relativo.. solo es saberlo tratar cuando se use, o tratar de no mezclar los namespaces al usar variables con el mismo nombre.
- La unica vez que debe importar el uso de import en vez de from es cuando se usa el mismo atributo definido en dos modulos distintos. Ejemplo:
# M.py
def func():
..... algo de codigo...
# N.py
def func():
.... algo de codigo...
Si va a utilizar ambas versiones del nombre en su programa, from fallará!
# O.py
from M import func
from N import func
func() # Invoca N.func()
Mejor estilo:
# O.py
import M, N
M.func()
N.func()
Namespaces en módulos:
Los módulos corresponden a archivos, y python crea un objeto modulo que contiene todos los nombres asignados en ese archivo módulo. O sea que simplemente son namespaces (lugar donde se crean los nombres, los cuales vienen siendo atributos).
Atributo: Todo nombre asignado a un valor en el nivel superior de un archivo modulo (no anidado en una función o clase) viene siendo un atributo de ese módulo.
- Sentencias en el módulo corren en el 1er import (orden de arriba a abajo)
- Asigaciones de mas alto nivel crean atributos del módulo.
- namespaces del modulo pueden ser accedidos via __dict__ o dir(módulo).
- Módulos son de alcance simple (local es global) .
Ejemplo:
modulo2.py:
print('iniciando carga...')
import sys
nombre = 42
def func(): pass
class klass: pass
print('terminando de cargar.' )
Importarlo desde el intérprete:
>>> import modulo2
iniciando carga...
carga hecha.
Accediendo a sys desde el namespace de modulo2:
>>> modulo2.sys
<module 'sys' (built-in)>
atributo nombre:
>>> modulo2.nombre
42
función:
>>> modulo2.func
<function func at 0x1d4db90>
clase:
>>> modulo2.klass
<class modulo2.klass at 0x1d30390>
namespaces del modulo es un diccionario:
>>> list(modulo2.__dict__.keys())
['__builtins__', '__file__', '__package__', 'sys', 'klass', 'func', 'nombre', '__name__', '__doc__']
Calificación de nombre de atributos
objeto.atributo
Reglas:
Variable simple: X significa buscar a X para el scope actual.
Calificacion: X.Y significa encontrar X en el scope actual, luego buscar atributo Y en el objeto X
Rutas de Calificación: X.Y.Z, buscar el nombre Y en el objeto X, luego buscar a Z en el objeto X.Y
Imports vs Scopes
considere los siguientes dos modulos simples:
moda.py:
X = 88 # X es global a ese archivo
def f():
global X #Cambiar X global
X = 99
modb.py
X = 11 # X: global al archivo
import moda # Ganar acceso a nombres en moda.
moda.f() # Pone moda.X, no el global X
print(X, moda.X) #
$ python modb.py
11 99
El programa Main:
Ejecutar una aplicación Python normalmente inicia con un script de nivel superior (o programa principal (main program). Este ejecuta como cualquier otro modulo cargado excepto que Python guarda el bytecode en memoria sin guardarlo a disco. El nombre del módulo para el programa principal siempre será __main__, junto con la variable global __name__ .
if __name__ == '__main__':
Recargando Modulos:
Para forzar un modulo y rearrancarlo, necesitas de la función reload. la función reload permite partes de un programa ser cambiadas sin detener el programa completo. Solo funciona con Python, C puede dinamicamente cargarlo en runtime, pero no puede ser recargado.
- reload es una funcion python, no una sentencia.
- reload es pasado a un objeto de modulo existente, no un nombre.
- reload pertenece a un modulo en Python 3.0, y debe ser importado.
- reload espera un objeto, previamente cargado satisfactoriamente.
- reload sobreescribe su namspace existente, mas alla de eliminarlo y re-crearlo.
- Asignaciones de nivel superior en el archivo reemplazan los nombres con nuevos valores.
- from no se afecta por reload.
Ejemplo:
Escribe un modulo llamado changer.py:
message = "Primera version"
def printer():
print(message)
Inicie el intérprete Python, importe el modulo y llame la función que exporta. Imprimirá el valor global de la variable message:
>>> import changer
>>> changer.printer()
Primera version
Mantenga el interprete activo, ahora edite el archivo módulo en otra ventana:
$ vi changer.py
Cambie la variable global message, como tambien el cuerpo de la función printer:
message = "Luego de editarlo"
def printer():
print('recargado:', message)
De vuelta al interprete Python:
>>> import changer
>>> changer.printer() # No ocurre ningun cambio
Primera version
from imp import reload
reload(changer) # Forza a usar nuevo codigo a cargar
<module 'changer' from 'changer.py'>
>>> changer.printer()
recargado: Luego de editarlo
Comments (0)
You don't have permission to comment on this page.