Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Aunque Python tiene relativamente pocas trampas o gotchas comparado con otros
lenguajes, sigue teniendo algunas construcciones que slo son de utilidad en situaciones
muy especficas, o que son sencillamente peligrosas.
A nivel de mdulo
Aunque from modulo import * es perfectamente vlido a nivel de mdulo,
normalmente su uso sigue siendo una mala idea. En primer lugar porque al utilizarlo
perdemos una importante propiedad de Python - y es que puedes saber dnde se define
cada nombre de primer nivel simplemente usando la funcin de bsqueda de tu editor.
Adems te arriesgas a encontrarte con errores en el futuro, si alguno de los mdulos
incorpora nuevas funciones o clases.
Una de las preguntas ms horribles con las que te puedes encontrar en los grupos de
noticias es por qu el siguiente cdigo no funciona:
view plaincopy to clipboardprint?
1. f = open("www")
2. f.read()
Por supuesto, funciona perfectamente (asumiendo que tienes un archivo llamado
"www"). Pero no funciona si tenemos un from os import * en algn lugar del
mdulo. El mdulo os tiene una funcin llamada open() que devuelve un entero.
Aunque algunas veces pueda resultar de utilidad, sobre escribir las funciones por
defecto es uno de los efectos colaterales ms molestos.
Recuerda, nunca ests seguro de los nombres que exporta un mdulo, as que importa
slo lo que necesites -- from modulo import nombre1, nombre2, o manten cada cosa
en su mdulo y accede a ellos cuando lo necesites import modulo;print
modulo.nombre.
Cundo es adecuado
Bien:
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
d = {}
for name in sys.argv[1:]:
d[name] = 1
def func(s, **kw):
for var, val in kw.items():
setattr(s, var, val)
d={}
execfile("handle.py", d, d)
handle = d['handle']
handle()
1. # foo.py
2. a = 1
3.
4. # bar.py
5. from foo import a
6. if algo():
7.
a = 2 # cuidado: foo.a != a
Bien:
view plaincopy to clipboardprint?
1. # foo.py
2. a = 1
3.
4. # bar.py
5. import foo
6. if algo():
7.
foo.a = 2
except:
Python cuenta con una clusula except: que sirve para capturar todas las excepciones.
Como todos los errores en Python producen excepciones, esto provoca que muchos
errores de programacin parezcan errores en tiempo de ejecucin, y dificulta el trabajo
de depuracin.
En el siguiente cdigo podemos ver un buen ejemplo:
view plaincopy to clipboardprint?
1. try:
2.
3. except:
4.
La segunda lnea lanza una excepcin de tipo NameError el cual se captura por la
clausula except. El programa terminar, y no tendrs ni idea de que esto no tiene nada
que ver con que se pueda o no leer "archivo".
El siguiente ejemplo est mejor escrito
view plaincopy to clipboardprint?
1. try:
2.
3. except IOError:
4.
Hay algunas situaciones en las que el uso de la clausula except: es adecuado, como en
el caso de un framework al ejecutar retrollamadas, no queremos que ninguna
retrollamada moleste al framework.
Excepciones
Las excepciones son una caracterstica muy til de Python. Deberas aprender a
lanzarlas cuando ocurra algo inesperado, y capturarlas slo en los lugares en los que
puedas hacer algo por remediarlas.
El siguiente es un anti-modismo muy popular:
view plaincopy to clipboardprint?
1. def get_status(archivo):
2.
if not os.path.exists(archivo):
3.
4.
sys.exit(1)
5.
return open(archivo).readline()
try:
3.
4.
return open(file).readline()
except (IOError, OSError):
5.
6.
sys.exit(1)
En esta versin hay dos posibilidades, o bien el archivo se abre y se lee la lnea (por lo
que funciona incluso en conexiones NFS o SMB poco fiables), o se muestra el mensaje
y se aborta la ejecucin.
Aun as, get_status() asume demasiadas cosas -- que slo se utilizar en un script que
no se ejecutar por mucho tiempo y no, por ejemplo, en un programa que corra durante
das en un servidor. Por supuesto al llamar a la funcin se podra hacer algo como
view plaincopy to clipboardprint?
1. try:
2.
status = get_status(log)
3. except SystemExit:
4.
status = None
asi que intenta usar cuantas menos clausulas except mejor en tu cdigo -- normalmente
estas consistirn en un except que capture todo en main(), o en llamadas internas que
siempre deberan ejecutarse con xito.
Por lo tanto la mejor versin sera probablemente
view plaincopy to clipboardprint?
1. def get_status(file):
2.
return open(file).readline()
El cdigo que llama a la funcin puede lidiar con la excecpin si lo necesita (por
ejemplo, si prueba la funcin con varios archivos en un bucle), o simplemente dejar que
la excepcin se propague.
La ltima versin tampoco es muy buena -- debido a detalles de implementacin, el
archivo no se cerrar cuando se lance una excepcin hasta que el manejador termine, y
puede que no ocurra en alguna implementacin que no se base en C (como por ejemplo
Jython)
view plaincopy to clipboardprint?
1. def get_status(file):
2.
fp = open(file)
3.
try:
4.
5.
6.
return fp.readline()
finally:
fp.close()
Deberas tener en cuenta que esto es peligroso: un caracter de espacio perdido despus
del \ causara que la lnea no fuera correcta. En este caso, al menos se tratara de un
error de sintaxis, pero si el cdigo fuera:
view plaincopy to clipboardprint?
1. value = foo.bar()['first'][0]*baz.quux(1, 2)[5:9] \
2.
2.
Hace mucho tiempo el entusiasta de Python Tim Peters plasm de forma concisa los
principios de diseo por los que guiarse al escribir en Python segn el BDFL (NT:
Benevolent Dictator for Life o Dictador Benvolo de por Vida, en este caso Guido van
Rossum, el creador de Python) en 20 aforismos, de los cuales slo 19 han pasado a
forma escrita.
http://www.python.org/dev/peps/pep-0020/
Puedes decidir por ti mismo si te consideras un "Pythoneer" o un "Pythonista". Los
trminos tienen connotaciones algo distintas.
En caso de duda:
import this
La comunidad Python tiene sus propios estndares en lo que al estilo del cdigo se
refiere, listados en el PEP 8. Estos estndares son distintos a los de otras comunidades,
como C, C++, C#, Java, VisualBasic, etc.
Debido a que la indentacin y los espacios en blanco son tan importantes en Python, la
Gua de Estilo del Cdigo Python es prcticamente un estndar. Sera inteligente seguir
esta gua! La mayor parte de los proyectos de cdigo abierto y los proyectos caseros
siguen la gua de estilo casi al pie de la letra (o eso espero).
Espacios en blanco 1
Espacios en blanco 2
Aade un espacio despus de las comas "," en diccionarios, listas, tuplas, y listas
de parmetros, y despus de los dos puntos ":" en los diccionarios, pero no antes.
Nombres
minusculas_con_guiones
minusculas_con_guiones
PalabrasEnMayusculas
camelCase
el cdigo
Lneas largas
Mantn las lneas de cdigo por debajo de los 80 caracteres.
Aprovecha que las sentencias continan en la siguiente lnea de forma implcita dentro
de parntesis/llaves/corchetes:
def __init__(self, primero, segundo, tercero,
cuarto, quinto, sexto):
salida = (primero + segundo + tercero
+ cuarto + quinto + sexto)
Las barras invertidas no son un mecanismo robusto; tienen que situarse al final de la
lnea. Si aadieras un espacio despus de la barra invertida, dejara de funcionar.
Adems, afean el cdigo.
Cadenas largas
El parseador concatena los literales de cadena adyacentes automticamente:
>>> print 'u' 'n' "o"
uno
Los espacios entre las cadenas no son necesarios, pero ayudan a la legibilidad. Se puede
utilizar cualquier tipo de comillas:
>>> print 't' r'\/\/' """o"""
t\/\/o
La cadena con una "r" como prefijo es una cadena "raw" (cruda). En las cadenas raw las
barras invertidas no se consideran caracteres de escape. Son tiles para las expresiones
regulares y las rutas del sistema de ficheros de Windows.
Ten en cuenta que las variables cadena no se concatenan automaticamente:
>>> a = 'tres'
>>> b = 'cuatro'
>>> a b
File "<stdin>", line 1
a b
^
SyntaxError: invalid syntax
Observa que en el ltimo ejemplo (el de las triples comillas simples), se utilizan barras
invertidas para escapar los caracteres de nueva lnea. Esto elimina los retornos de carro
extra, proporcionando una estructura muy legible, con el texto y las comillas justificadas
a la izquierda. Las barras invertidas se deben colocar al final de las respectivas lneas.
Sentencias compuestas
Bien:
if foo == 'bla':
haz_algo()
haz_primero()
haz_segundo()
haz_tercero()
Mal:
if foo == 'bla': haz_algo()
haz_primero(); haz_segundo(); haz_tercero()
El espacio en blanco y la indentacin son indicadores visuales muy buenos del flujo del
programa. La indentacin de la primera versin muestra al lector que algo est
ocurriendo, mientras que la falta de indentacin del segundo ejemplo hace que el "if"
pase ms desapercibido.
Utilizar varios estamentos en la misma lnea es un pecado capital. En Python, la
legibilidad cuenta.
Cadenas de documentacin y
comentarios
Cadenas de documentacin = Cmo usar el cdigo
Comentarios = Por qu (razones) y cmo funciona el cdigo
Las cadenas de documentacin explican cmo usar el cdigo, y estn destinadas a los
usuarios del cdigo. Usos de las cadenas de documentacin:
Describir los parmetros que espera la funcin, los valores de retorno, y las
excepciones que puede lanzar.
Los comentarios explican el por qu, y estn dirigidos a las personas que van a
mantener tu cdigo. Puedes incluir notas para t mismo, como:
# !!! BUG: ...
# !!! FIX: Esto es una chapuza
# ??? Por qu est esto aqu?
Popurr de modismos
Una seleccin de idioms o modismos pequeos y tiles.
Pasemos ahora a la parte importante del tutorial: montones de modismos.
Vamos a comenzar con algunos ms sencillos e iremos aumentando el nivel poco a
poco.
Intercambiar valores
En otros lenguajes:
temporal = a
a = b
b = temporal
En Python:
b, a = a, b
Puede que hayas visto esto antes. Pero sabas cmo funciona?
Se crea una tupla a la derecha del igual (empaquetamos los valores en una
tupla).
Son tiles para usar en bucles que iteran sobre datos estructurados:
(L) es la lista que acabamos de crear (los datos de David). As que personas es una
lista que contiene dos elementos, siendo cada uno de ellos una lista de 3 elementos.
l
No te olvides de la coma!
>>> (1)
1
En una tupla de un solo elemento, es necesario aadir una coma al final; en tuplas de 2
elementos o ms, la coma al final es opcional. Para tuplas vacas se puede utilizar un par
de parntesis para atajar:
>>> ()
()
>>> tuple()
()
Un fallo muy comn es aadir una coma incluso cuando lo que buscas no es una tupla.
Es fcil no darse cuenta de que hay una coma en el cdigo:
>>> valor = 1,
>>> valor
(1,)
Por lo tanto, si ves una tupla en un lugar donde no debera existir, comprueba las
comas!
"_" interactivo
Esta es una caracterstica muy til aunque, sorprendentemente, muy poca gente la
conoce.
En el intrprete interactivo, cada vez que evalas una expresin o llamas a una funcin,
el resultado se almacena en una variable temporal llamada _ (un guin bajo):
>>> 1 + 1
2
>>> _
2
_
Ahora queremos unir todas las cadenas en una cadena ms larga. Especialmente cuando
tenemos un gran nmero de subcadenas...
No hagas esto:
resultado = ''
for s in colores:
resultado += s
O comas y espacios:
resultado = ', '.join(colores)
Para que la frase tenga ms sentido gramticamente, pondremos comas entre todos los
valores a excepcin del ltimo par, donde queremos la palabra "o". El particionado de
listas es la herramienta adecuada para el trabajo. Con [:-1] obtenemos todos los
valores a excepcin del ltimo, y los unimos utilizando una coma y un espacio.
Por supuesto, este ejemplo no funcionara para listas de 0 o 1 elementos.
Salida:
Esto requiere del uso de una expresin generadora, que cubriremos en profundidad ms
tarde.
Si necesitas construir las subcadenas de forma incremental, primero adelas a una lista:
items = []
...
items.append(item) # varias veces
...
# items ya esta completo
resultado = ''.join(funcion(i) for i in items)
Aadimos las partes a una lista de forma que podamos usar el mtodo join por
cuestiones de eficiencia.
Normalmente in es ms rpido.
in
Mal:
for clave in d.keys():
print clave
crea una lista esttica de las claves del diccionario. De otra forma, se lanzara
una excepcin "RuntimeError: dictionary changed size during iteration" (el tamao del
diccionario cambi durante la iteracin).
d.keys()
navs = {}
for (portfolio, acciones, posicion) in data:
navs[portfolio] = (navs.get(portfolio, 0)
+ position * precios[acciones])
Mucho ms sencillo.
acciones.setdefault(portfolio, []).append(
accion)
pero nosotros lo
ignoramos. Lo que estamos haciendo es aprovechar un efecto secundario de
setdefault, que es el de asignar el valor del diccionario slo si no existe ya un valor
para esa clave.
defaultdict
toma un parmetro extra como primer argumento: una funcin de factora por
defecto; y
cuando se accede a una clave del diccionario por primera vez, se llama a la
funcin de factora por defecto y el resultado se utiliza para inicializar el valor
del diccionario para esa clave.
import collections
d = collections.defaultdict(...)
from collections import defaultdict
d = defaultdict(...)
A continuacin tenemos el ejemplo que vimos anteriormente, en el que cada valor del
diccionario deba inicializarse a una lista vaca, reescrito usando defaultdict:
from collections import defaultdict
acciones = defaultdict(list)
for (portfolio, accion) in datos:
acciones[portfolio].append(accion)
la
>>> pythons.keys()
['John', 'Michael', 'Eric', 'Terry']
>>> pythons.values()
['Cleese', 'Palin', 'Idle', 'Gilliam']
Observa que el orden del resultado de .keys() y .values() es distinto del de los elementos
de las listas utilizadas para construir el diccionario. El orden de entrada es diferente del
orden de salida. Esto es debido a que los diccionarios son colecciones no ordenadas. Por
otro lado, el orden ser siempre consistente (esto es, el orden de las claves se
corresponder con el de los valores), siempre y cuando el diccionario no se haya
cambiado entre llamadas.
# haz esto:
if x:
pass
# no esto:
if x == True:
pass
# no esto:
if len(items) != 0:
pass
# y menos esto:
if items != []:
pass
Valores booleanos
Los nombres True y False son instancias del tipo bool, valores Booleanos. Como
None, slo hay una instancia de cada uno de ellos.
False
True
False
""
(== 0)
(cadena vaca)
True
(== 1)
0, 0.0
None
return len(self.data)
Supongamos que quieres iterar sobre los elementos de la lista, y que necesitamos tanto
el ndice como el elemento en s:
- o i = 0
for item in items:
print i, item
i += 1
for i in range(len(items)):
print i, items[i]
es una funcin
lazy: genera los elementos uno a uno, un par cada vez, slo cuando se requieren. Un
bucle for es un lugar en el que se requiere un elemento cada vez. enumerate es un
ejemplo de un generador, que trataremos ms detenidamente ms adelante. print no
utiliza un elemento cada vez -- queremos el resultado completo, as que hay que
convertir el generador explcitamente en una lista al imprimirlo.
De esta forma nuestro bucle es mucho ms simple:
int a = 1;
a = 2;
int b = a;
"b" es una segunda caja, con una copia del entero 2. La caja "a" tiene una copia
totalmente independiente.
a = 1
En este caso, el objeto entero 1 tiene una etiqueta con texto "a".
Si reasignarmos "a", lo que hacemos es colocar la etiqueta a otro objeto:
a = 2
b = a
El nombre "b" es slo una segunda etiqueta aadida al mismo objeto que "a".
Aunque en Python normalmente tambin usamos el trmino "variables" (porque es
terminologa comn), en realidad nos estamos refiriendo a "nombres" o
"identificadores". En Python, las "variables" son etiquetas con nombres para los valores,
no cajas con nombres.
Aunque no aprendas nada ms de este tutorial, espero que al menos hayas entendido
cmo funcionan los nombres en Python. Entender este punto te dar buenos dividendos,
ayudndote a evitar casos como este:
Las listas son objetos mutables; puedes modificar su contenido. La forma correcta de
obtener una lista por defecto (o diccionario, o conjunto) es crearla en tiempo de
ejecucin, dentro de la funcin:
def anyadir_correcto(nuevo_item, una_lista=None):
if una_lista is None:
una_lista = []
una_lista.append(nuevo_item)
return una_lista
% Formateo de cadenas
El operador % de Python funciona de forma similar al de la funcin sprintf de C.
Aunque si no sabes C, este dato no te ser de mucha utilidad. Basicamente, puedes
establecer una plantilla o formato para los valores.
Salida:
Hola David, tienes 3 mensajes
En este caso especificas los nombres de los valores a interpolar, los cuales se buscan en
el diccionario que se pasa como argumento.
Notas la redundancia? Los nombres "nombre" y "mensajes" ya estn definidos en el
espacio de nombres local. Podemos aprovecharnos de esto.
Por nombre, usando el espacio de nombres local:
print ('Hola %(nombre)s, tienes %(mensajes)i '
'mensajes' % locals())
Pero el poder puede ser peligroso. ("Un gran poder conlleva una gran responsabilidad.")
Si utilizas locals() con una plantilla proporcionada de forma externa, expones tu
espacio de nombres local completamente al llamador. Esto es algo a tener en cuenta.
Para examinar tu espacio de nombres local:
>>> from pprint import pprint
>>> pprint(locals())
pprint es un mdulo muy til. Si no
Comprensin de listas
La comprensin de listas ("listcomps" para abreviar) son atajos sintcticos para el
siguiente patrn:
La forma tradicional, con un bucle for y sentencias if:
nueva_lista = []
for item in una_lista:
if condicion(item):
nueva_lista.append(fn(item))
La compresin de listas es muy clara y concisa, hasta cierto punto. Puedes tener varios
bucles for y varias condiciones if, pero a partir de dos o tres, o si las condiciones son
algo complejas, te sugiero utilizar bucles for normales. Aplicando el Zen de Python,
elige la forma ms legible.
Por ejemplo, una lista de los cuadrados de 09:
secuencia.
Como comprensin de listas:
total = sum([num * num for num in range(1, 101)])
La diferencia en la sintaxis es que las listcomps utilizan corchetes, mientras que las
expresiones generadoras no lo hacen. Las expresiones generadoras necesitan colocarse
entre parntesis a veces, as que deberas acostumbrarte a utilizarlos.
Regla general:
Utiliza comprensin de listas cuando la lista sea el resultado que nos interesa.
Necesitbamos un diccionario que mapeara los nmeros de los meses (tanto en forma de
enteros como de cadenas) a cdigos de meses para futuros contratos. Podra hacerse en
una sola lnea de cdigo.
Tenemos una lista de cdigos para los meses (cada cdigo es una nica letra, y
una cadena no es ms que una lista de letras). Usamos enumerate sobre la lista
para obtener tanto el mes como el ndice.
Los nmeros de los meses comienzan con 1, pero en Python los ndices
comienzan en 0, as que el nmero de mes es el ndice ms uno.
Queremos buscar los meses tanto por cadenas como por enteros. Podemos usar
las funciones int() y str() para hacerlo por nosotros, e iterar sobre ellos.
Ejemplo reciente:
codigos_meses = dict((fn(i+1), codigo)
for i, codigo in enumerate('FGHJKMNQUVXZ')
for fn in (int, str))
Ordenando
Ordenar listas en Python es muy sencillo:
a_list.sort()
(Ten en cuenta que se ordena la lista original, el mtodo sort no devuelve una lista o
una copia de la lista ordenada.)
Pero, qu ocurre si tenemos una lista de datos a ordenar, pero el orden no es el normal
(es decir, ordenar por la primera columna, despus la segunda, etc.)? Puede que
necesitemos ordenar por la segunda columna y luego por la cuarta.
Podemos usar el mtodo sort indicando una funcin propia para comparar:
def mi_comparador(item1, item2):
returm cmp((item1[1], item1[3]),
(item2[1], item2[3]))
una_lista.sort(mi_comparador)
La primera lnea crea una lista que contiene tuplas: copias de elementos a ordenar en
orden de prioridad, seguidos de los datos completos.
La segunda lnea utiliza la ordenacin nativa de Python, que es muy rpida y eficiente.
La tercera lnea obtiene el ltimo valor de la lista ordenada. Recuerda, este ltimo valor
son los datos completos. Descartamos los elementos que usamos para ordenar, que ya
no necesitamos ms.
Se trata entonces de un compromiso entre espacio y complejidad frente a tiempo. Es
ms sencillo y rpido, pero necesitamos duplicar la lista original.
a_ordenar.sort(key=mi_clave)
La funcin mi_clave se llama una vez para cada elemento de la lista a_ordenar.
Puedes crear tus propias funciones para calcular la clave, o utilizar cualquier funcin de
un slo parmetro que se ajuste a tus necesidades:
str.lower
minsculas.
len
int
Generadores
Ya hemos visto las expresiones generadoras. Podemos crear expresiones generadoras
tan complejas como queramos, como funciones:
def mi_generador_range(parada):
valor = 0
while valor < parada:
yield valor
valor += 1
for i in mi_generador_range(10):
haz_algo(i)
La palabra clave yield convierte una funcin en un generador. Cuando llamas a una
funcin generadora, en lugar de devolver el valor de retorno inmediatamente Python
devuelve un objeto generador, que es un iterador; tiene un mtodo next. Los bucles for
simplemente llaman al mtodo next del iterador, hasta que se lanza una excepcin
StopIteration. Puedes lanzar una excepcin StopIteration de forma explcita, o
bien de forma implcita al llegar al final del cdigo del generador como en el ejemplo
anterior.
Los generadores pueden ayudar a simplificar el trabajo con secuencias/iteradores,
porque no necesitamos construir listas concretas; solo calculan un valor cada vez. La
funcin generadora mantiene el estado.
Esta es la forma en la que funciona un bucle for en realidad. Python comprueba la
secuencia que se pasa despus de la palabra clave in. Si es un contenedor simple (como
una lista, una tupla, un diccionario, un conjunto, o un contenedor creado por el usuario)
Python lo convierte en un iterador. Si ya es un iterador no hace nada.
Entonces Python llama repetidamente al mtodo next del iterador, asigna el valor
devuelto al contador del bucle (i en este caso), y ejecuta el cdigo indentado. El
proceso se repite una y otra vez, hasta que se lanza la excepcin StopIteration, o se
ejecuta una sentencia break.
Un bucle for puede tener una clausula else, cuyo cdigo se ejecuta despus de que el
iterador se quede sin elementos, pero no si se sale al ejecutar un break. Esta distincin
permite usos muy elegantes. Las clusulas else no se suelen utilizar mucho con los
bucles for, pero pueden ser muy tiles. Algunas veces una clusula else es la mejor
forma de expresar la lgica que necesitas.
Por ejemplo, si necesitas comprobar que una condicin se cumple para todos los
elementos de una secuencia:
for item in secuencia:
if condition(item):
break
else:
raise Exception('La condicion no se satisface.')
Generadores de ejemplo
Filtrar lneas en blanco de un archivo CSV (o elementos de una lista):
def filtrar_filas(iterador_filas):
for fila in iterador_filas:
if fila:
yield fila
archivo_datos = open(ruta, 'rb')
ifilas = filtrar_filas(csv.reader(archivo_datos))
Esto es posible porque los archivos soportan el mtodo next, como otros iteradores:
listas, tuplas, diccionarios (para sus claves), generadores.
Aunque hay que tener cuidado con una cosa: debido a la forma en la que funciona el
buffer de datos, no puedes mezclar los mtodos .next y .read* a menos que utilices
Python 2.5+.
Excepciones
Si x debe ser una cadena para que el cdigo funcione, por qu no escribir
str(x)
return str(x)
except TypeError:
...
Nota: Especifica siempre las excepciones a capturar. Nunca uses clusulas except sin
indicar el tipo de la excepcin. Esto podra capturar excepciones no esperadas, haciendo
que tu cdigo fuera ms dificil de depurar.
Importando
from modulo import *
Es probable que hayas visto esta forma con un "carcter comodn" de las sentencias
import. Puede que incluso te guste. No lo utilices.
Parafraseando una dilogo muy conocido:
(Dagobah, jungla, pantanos, y niebla.)
LUKE: Es mejor from module import * que los imports explcitos?
YODA: No, no mejor. Ms rpido, ms fcil, ms seductor.
LUKE: Pero cmo sabr por qu los imports explcitos son mejores que la forma con
el carcter comodn?
YODA: Saberlo tu podrs cuando tu cdigo intentes leer seis meses despus.
Los carcteres comodn en los imports pertenecen al lado oscuro de la fuerza de Python.
Nunca!
El uso de from module import * conlleva polucin del espacio de nombres. Tendrs
montones de cosas en el espacio de nombres local que no esperabas tener. Puede que te
encuentres con nombres importados sobreescribiendo nombres definidos en local. No
podrs distinguir fcilmente de dnde vienen algunos nombres. Aunque pueda ser un
atajo conveniente, no debera utilizarse en cdigo en produccin.
Moraleja: no uses el carcter comodn para los imports!
Es mucho mejor:
Modulos y Scripts
Para crear un mdulo que se pueda importar y tambin ejecutar como si de un script se
tratara:
if __name__ == '__main__':
# codigo del script
Al importar un mdulo su atributo __name__ toma como valor el nombre del archivo
que define el mdulo, sin el ".py". De forma que el cdigo de la sentencia if no se
ejecutar al importarse el mdulo. Cuando se ejecuta como un script el atributo
__name__ tiene como valor "__main__", por lo que, ahora s, se ejecutar el cdigo del
script.
A excepcin de algunos pocos casos especiales, no deberas colocar ningn cdigo
ejecutable en el primer nivel del cdigo. Colocalo en funciones, clases, mtodos, y
controla su ejecucin usando if __name__ == '__main__'.
Estructura de un mdulo
"""Cadena de documentacion del modulo"""
#
#
#
#
#
#
imports
constantes
clases de tipo excepcion
funciones para uso publico
clases
funciones y clases internas
def main(...):
...
if __name__ == '__main__':
estado = main()
sys.exit(estado)
Paquetes
paquete/
__init__.py
modulo1.py
subpaquete/
__init__.py
modulo2.py
Ejemplo:
import paquete.modulo1
from paquetes.subpaquete import modulo2
from paquetes.subpaquete.modulo2 import nombre
En Python 2.5 contamos con imports relativos y absolutos a travs de future import:
from __future__ import absolute_import
No reinventes la rueda
Antes de escribir cualquier cdigo,
Referencias