<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>denklab | Artículos en la categoría »PyMOTW«</title><link>http://denklab.org/articles/category/pymotw/</link><description>Artículos en la categoría »PyMOTW«</description><language>es</language><lastBuildDate>Sun, 21 Sep 2008 23:09:21 -0400</lastBuildDate><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/denklabpymotwarticles" type="application/rss+xml" /><item><title>PyMOTW: anydbm (y módulos relacionados)
</title><link>http://feedproxy.google.com/~r/denklabpymotwarticles/~3/YvXqQCwNJxE/</link><description>&lt;p&gt;Traducción de &lt;a href="http://www.doughellmann.com/PyMOTW/anydbm/"&gt;PyMOTW: anydbm&lt;/a&gt; el módulo &lt;code&gt;anydbm&lt;/code&gt; y módulos relacionados de la columna semana de &lt;a href="http://www.doughellman.com/"&gt;Doug Hellman&lt;/a&gt; 
&lt;/p&gt;



&lt;hr noshade&gt;


&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Módulo:&lt;/th&gt;
        &lt;td&gt;&lt;a href=""&gt;anydbm&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Propósito:&lt;/th&gt;
        &lt;td&gt;El módulo anydbm proporciona una interfaz genérica similar a diccionarios para base de datos del estilo DBM con cadenas como llaves.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Versión de Python:&lt;/th&gt;
        &lt;td&gt;1.4 y posterior&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt; &lt;code&gt;anydbm&lt;/code&gt; es un &lt;em&gt;front-end&lt;/em&gt; para bases de datos del estilo DBM que usan cadenas
   (de texto) simples como llaves para acceder a registros que contienen cadenas.
   Utiliza el módulo &lt;code&gt;whichdb&lt;/code&gt; para identificar bases de datos &lt;code&gt;dbhash&lt;/code&gt;, &lt;code&gt;gdbm&lt;/code&gt; y
   &lt;code&gt;dbm&lt;/code&gt;, luego las abre con el módulo apropiado.  Es usado como &lt;em&gt;backend&lt;/em&gt; para
   &lt;code&gt;shelve&lt;/code&gt;, que sabe como guardar objetos usando &lt;code&gt;pickle&lt;/code&gt;.
&lt;/p&gt;

&lt;h3&gt;Creando una nueva base de datos&lt;/h3&gt;
&lt;p&gt;El formato de almacenamiento para nuevas bases de datos es seleccionado buscando cada uno de estos módulo en orden:
&lt;/p&gt;
&lt;ul&gt;
 &lt;li&gt;
      &lt;code&gt;dbhash&lt;/code&gt; 
 &lt;/li&gt;

 &lt;li&gt;
      &lt;code&gt;gdbm&lt;/code&gt; 
 &lt;/li&gt;

 &lt;li&gt;
      &lt;code&gt;dbm&lt;/code&gt; 
 &lt;/li&gt;

 &lt;li&gt;
      &lt;code&gt;dumbdbm&lt;/code&gt; 
 &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La función &lt;code&gt;open()&lt;/code&gt; acepta &lt;em&gt;flags&lt;/em&gt; para controlar como es gestionado el
   archivo de base de datos.  Para crea una base de datos nuevo cuando sea
   necesario, usa &lt;code&gt;'c'&lt;/code&gt;.  Para crear una nueva base de datos siempre, usa &lt;code&gt;'n'&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import anydbm

db = anydbm.open('/tmp/ejemplo.db', 'n')
db['llave'] = 'valor'
db['hoy'] = 'Domingo'
db['autor'] = 'Ernesto'
db.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En este ejemplo, el archivo siempre es re inicializado.  Para ver qué tipo de
   base de datos ha sido creada, podemos usar &lt;code&gt;whichdb&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import whichdb

print whichdb.whichdb('/tmp/ejemplo.db')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Los resultado pueden variar dependiendo qué módulos están instalados en tu
   sistema.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python anydbm_whichdb.py
dbhash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Abriendo una base de datos existente&lt;/h3&gt;
&lt;p&gt;Para abrir una base de datos existente, usa &lt;em&gt;flags&lt;/em&gt; &lt;code&gt;'r'&lt;/code&gt; (para sólo lectura) o
   &lt;code&gt;'w'&lt;/code&gt; (para lectura y escritura).  No necesitas preocuparte por el formato,
   porque bases de datos existentes son automáticamente se dan &lt;code&gt;whichdb&lt;/code&gt; para su
   identificación.  Si un file puede ser identificado, el módulos apropiado es
   utilizado para abrirlo.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import anydbm

db = anydbm.open('/tmp/ejemplo.db', 'r')
try:
    print 'keys():', db.keys()
    for k, v in db.iteritems():
        print 'iterando:', k, v
    print 'db[&amp;quot;autor&amp;quot;] =', db['autor']
finally:
    db.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Una vez abierto, &lt;code&gt;db&lt;/code&gt; es un objeto similar a un diccionario, con soporte para
   los métodos habituales.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python anydbm_existing.py
keys(): ['llave', 'hoy', 'autor']
iterando: llave valor
iterando: hoy Domingo
iterando: autor Ernesto
db[&amp;quot;autor&amp;quot;] = Ernesto
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Casos de error&lt;/h3&gt;
&lt;p&gt;Las llaves de la base de datos tienen que ser cadenas.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import anydbm

db = anydbm.open('/tmp/ejemplo.db', 'w')
try:
    db[1] = 'uno'
finally:
    db.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pasar otro tipo (de objeto) resulta en un &lt;code&gt;TypeError&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python anydbm_intkeys.py
Traceback (most recent call last):
  File &amp;quot;anydbm_intkeys.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;
    db[1] = 'uno'
  File &amp;quot;/home/ers/Projects/PyMOTW-es/anydbm/__init__.py&amp;quot;, line 230, in __setitem__

  File &amp;quot;bsddb/dbutils.py&amp;quot;, line 62, in DeadlockWrap
  File &amp;quot;/home/ers/Projects/PyMOTW-es/anydbm/__init__.py&amp;quot;, line 229, in wrapF

TypeError: Integer keys only allowed for Recno and Queue DB's
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Los valores tienen que ser cadenas o &lt;code&gt;None&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import anydbm

db = anydbm.open('/tmp/ejemplo.db', 'w')
try:
    db['uno'] = 1
finally:
    db.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Un &lt;code&gt;TypeError&lt;/code&gt; similar es lanzado si el valor no es una cadena.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python anydbm_intvalue.py
Traceback (most recent call last):
  File &amp;quot;anydbm_intvalue.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;
    db['uno'] = 1
  File &amp;quot;/home/ers/Projects/PyMOTW-es/anydbm/__init__.py&amp;quot;, line 230, in __setitem__

  File &amp;quot;bsddb/dbutils.py&amp;quot;, line 62, in DeadlockWrap
  File &amp;quot;/home/ers/Projects/PyMOTW-es/anydbm/__init__.py&amp;quot;, line 229, in wrapF

TypeError: Data values must be of type string or None.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Referencias&lt;/h3&gt;
&lt;p&gt; &lt;a href="http://www.doughellmann.com/PyMOTW/"&gt;PyMOTW Home&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://www.doughellmann.com/downloads/PyMOTW-1.69.tar.gz"&gt;Descarga los ejemplos&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://docs.python.org/lib/module-anydbm.html"&gt;Documentación biblioteca estándar: anydbm&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt; &lt;a href="http://denklab.org/copyright/pymotw/"&gt;Copyright&lt;/a&gt; 2008 &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/denklabpymotwarticles/~4/YvXqQCwNJxE" height="1" width="1"/&gt;</description><pubDate>Sun, 21 Sep 2008 23:09:21 -0400</pubDate><guid isPermaLink="false">http://denklab.org/articles/2008/9/pymotw-anydbm-y-modulos-relacionados/</guid><feedburner:origLink>http://denklab.org/articles/2008/9/pymotw-anydbm-y-modulos-relacionados/</feedburner:origLink></item><item><title>PyMOTW: exceptions
</title><link>http://feedproxy.google.com/~r/denklabpymotwarticles/~3/kdYbBpOnth4/</link><description>&lt;p&gt;Traducción de &lt;a href="http://www.doughellmann.com/PyMOTW/exceptions/"&gt;PyMOTW: exceptions&lt;/a&gt;, el módulo  &lt;code&gt;exceptions&lt;/code&gt; de la columna semanal de &lt;a href="http://www.doughellman.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;



&lt;hr noshade&gt;


&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Módulo&lt;/th&gt;
        &lt;td&gt;&lt;a href="http://docs.python.org/lib/module-exceptions.html"&gt;exceptions&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Propósito&lt;/th&gt;
        &lt;td&gt;El módulo exceptions define los errores incorporados que se usan en la biblioteca estándar y por el intérprete.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Versión de Python&lt;/th&gt;
        &lt;td&gt;1.5 y posterior&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;


&lt;h3&gt;Descripción&lt;/h3&gt;
&lt;p&gt;En el pasado, Python ha soportado cadenas simples de mensajes como excepciones
   así como clases.  Desde la versión 1.5, todos los módulos de la biblioteca
   estándar usan clases para excepciones.  A partir de Python 2.5, excepciones de
   cadenas resultan en una advertencia &lt;code&gt;DeprecationWarning&lt;/code&gt;, y el soporte para
   excepciones de cadenas va a ser retirado en el futuro.
&lt;/p&gt;

&lt;h3&gt;Clases base&lt;/h3&gt;
&lt;p&gt;Las clases de excepciones están definidas en una jerarquía, que está descrita
   en la documentación de la biblioteca estándar.  Adicionalmente a los beneficios
   obvios de organización, la herencia de excepciones es útil porque excepciones
   relacionadas pueden ser atrapadas atrapando su clase base.  En la mayoría de
   los casos, estas clases base no están destinadas a ser lanzadas directamente.
&lt;/p&gt;

&lt;h4&gt;BaseException&lt;/h4&gt;
&lt;p&gt;Clase base para todas las excepciones.  Implementa la lógica para crear una
   cadena que represente la excepciones usando &lt;code&gt;str()&lt;/code&gt; con los argumentos que se
   pasan al constructor.
&lt;/p&gt;

&lt;h4&gt;Exception&lt;/h4&gt;
&lt;p&gt;Clase base para excepciones que no resultan en la terminación de la aplicación
   que se está ejecutando.  Todas las excepciones definidas por el usuario
   deberían usar &lt;code&gt;Exception&lt;/code&gt; como clase base.
&lt;/p&gt;

&lt;h4&gt;StandardError&lt;/h4&gt;
&lt;p&gt;Clase base para excepciones incorporadas usadas en la biblioteca estándar.
&lt;/p&gt;

&lt;h4&gt;ArithmeticError&lt;/h4&gt;
&lt;p&gt;Clase base para errores matemáticos.
&lt;/p&gt;

&lt;h4&gt;LookupError&lt;/h4&gt;
&lt;p&gt;Clase base para errores que son lanzados cuando algo no puede ser encontrado.
&lt;/p&gt;

&lt;h4&gt;EnvironmentError&lt;/h4&gt;
&lt;p&gt;Clase base para errores que vienen de fuera de Python (el sistema operativo, el
   sistema de archivos, etc.).
&lt;/p&gt;

&lt;h3&gt;Excepciones lanzadas&lt;/h3&gt;

&lt;h4&gt;AssertionError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;AssertionError&lt;/code&gt; es lanzado por una instrucción &lt;code&gt;assert&lt;/code&gt; fallida.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;assert False, 'La afirmación ha fallado'

$ python exceptions_AssertionError_assert.py
Traceback (most recent call last):
  File &amp;quot;exceptions_AssertionError_assert.py&amp;quot;, line 12, in &amp;lt;module&amp;gt;
    assert False, 'La afirmación ha fallado'
AssertionError: La afirmación ha fallado
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;También es usado en el módulo &lt;code&gt;unittest&lt;/code&gt; en métodos como &lt;code&gt;failIf()&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import unittest

class AssertionExample(unittest.TestCase):

    def test(self):
        self.failUnless(False)

unittest.main()

$ python exceptions_AssertionError_unittest.py
F
======================================================================
FAIL: test (__main__.AssertionExample)
----------------------------------------------------------------------
Traceback (most recent call last):
  File &amp;quot;exceptions_AssertionError_unittest.py&amp;quot;, line 17, in test
    self.failUnless(False)
AssertionError

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;AttributeError&lt;/h4&gt;
&lt;p&gt;Cuando una referencia o una asignación a un atributo fallan, &lt;code&gt;AttributeError&lt;/code&gt; es
   lanzado.
&lt;/p&gt;
&lt;p&gt;Por ejemplo, cuando se trata de referencias a una atributo que no existe:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class NoAttributes(object):
    pass

o = NoAttributes()
print o.attribute

$ python exceptions_AttributeError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_AttributeError.py&amp;quot;, line 16, in &amp;lt;module&amp;gt;
    print o.attribute
AttributeError: 'NoAttributes' object has no attribute 'attribute'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;O cuando se trata de modificar un atributo sólo de lectura.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class MyClass(object):

    @property
    def attribute(self):
        return 'Este es el valor de attribute'

o = MyClass()
print o.attribute
o.attribute = 'Nuevo valor'

$ python exceptions_AttributeError_assignment.py
Este es el valor de attribute
Traceback (most recent call last):
  File &amp;quot;exceptions_AttributeError_assignment.py&amp;quot;, line 20, in &amp;lt;module&amp;gt;
    o.attribute = 'Nuevo valor'
AttributeError: can't set attribute
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;EOFError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;EOFError&lt;/code&gt; es lanzado cuando una función incorporada como &lt;code&gt;input()&lt;/code&gt; o
   &lt;code&gt;raw_input()&lt;/code&gt; no lee ningún dato antes de encontrar en final de su flujo de
   entrada.  Los métodos de archivo como &lt;code&gt;read()&lt;/code&gt; devuelven una cadena vacía al
   final del archivo.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while True:
    data = raw_input('prompt:')
    print 'LEIDO:', data

$ echo hello | python exceptions/exceptions_EOFError.py
prompt:LEIDO: hello
prompt:Traceback (most recent call last):
  File &amp;quot;exceptions_EOFError.py&amp;quot;, line 13, in &amp;lt;module&amp;gt;
    data = raw_input('prompt:')
EOFError: EOF when reading a line
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;FloatingPointError&lt;/h4&gt;
&lt;p&gt;Es lanzada por operaciones con números de coma flotante que resultan en
   errores, cuando el control de excepción de coma flotante (fpectl, &lt;em&gt;floating
point exception control&lt;/em&gt;) está activado.  Activar &lt;code&gt;fpectl&lt;/code&gt; requiere de un
   intérprete compilado con &lt;code&gt;--with-fpectl&lt;/code&gt;. El uso de &lt;code&gt;fpectl&lt;/code&gt; no se recomienda
   en la documentación de la biblioteca estándar
   http://docs.python.org/lib/module-fpectl.html.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import math
import fpectl

print 'Control desactivado:', math.exp(1000)
fpectl.turnon_sigfpe()
print 'Control activado:', math.exp(1000)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;GeneratorExit&lt;/h4&gt;
&lt;p&gt;Es lanzada dentro de un generador si el método &lt;code&gt;close()&lt;/code&gt; del generador es
   invocado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def my_generator():
    try:
        for i in range(5):
            print 'Rindiendo', i
            yield i
    except GeneratorExit:
        print 'Saliendo anticipadamente'

g = my_generator()
print g.next()
g.close()

$ python exceptions_GeneratorExit.py
Rindiendo 0
0
Saliendo anticipadamente
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;IOError&lt;/h4&gt;
&lt;p&gt;Es lanzada cuando la entrada o salida fallan, por ejemplo si un disco se llena
   o un archivo de entrada no existe.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f = open('/no/existe', 'r')

$ python exceptions_IOError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_IOError.py&amp;quot;, line 12, in &amp;lt;module&amp;gt;
    f = open('/no/existe', 'r')
IOError: [Errno 2] No such file or directory: '/no/existe'
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ImportError&lt;/h4&gt;
&lt;p&gt;Es lanzada cuando un módulo, o un miembro de un módulo no puede ser importado.
   Hay algunas condiciones en las que &lt;code&gt;ImportError&lt;/code&gt; puede ser lanzada.
&lt;/p&gt;
&lt;ol&gt;
 &lt;li&gt;&lt;p&gt;Si un módulo no existe.
&lt;/p&gt;
&lt;p&gt;import module_no_existe
&lt;/p&gt;
&lt;p&gt;$ python exceptions_ImportError_nomodule.py
   Traceback (most recent call last):
     File &amp;quot;exceptions_ImportError_nomodule.py&amp;quot;, line 12, in &lt;module&gt;
       import module_no_existe
   ImportError: No module named module_no_existe
&lt;/p&gt;

 &lt;/li&gt;

 &lt;li&gt;&lt;p&gt;Si &lt;code&gt;from X import Y&lt;/code&gt; es usado y &lt;code&gt;Y&lt;/code&gt; no puede ser encontrado dentro del módulo
      &lt;code&gt;X&lt;/code&gt;, un &lt;code&gt;ImportError&lt;/code&gt; es lanzado.
&lt;/p&gt;
&lt;p&gt;from exceptions import NombreInventado
&lt;/p&gt;
&lt;p&gt;$ python exceptions_ImportError_missingname.py
   Traceback (most recent call last):
     File &amp;quot;exceptions_ImportError_missingname.py&amp;quot;, line 12, in &lt;module&gt;
       from exceptions import NombreInventado
   ImportError: cannot import name NombreInventado
&lt;/p&gt;

 &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;IndexError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;IndexError&lt;/code&gt; es lanzado cuando una referencias en una secuencia está fuera
   de rango.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;my_seq = [ 0, 1, 2 ]
print my_seq[3]

$ python exceptions_IndexError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_IndexError.py&amp;quot;, line 13, in &amp;lt;module&amp;gt;
    print my_seq[3]
IndexError: list index out of range
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;KeyError&lt;/h4&gt;
&lt;p&gt;De manera similar, un &lt;code&gt;KeyError&lt;/code&gt; es lanzado cuando un valor no es encontrado
   como llave de un diccionario.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;d = { 'a':1, 'b':2 }
print d['c']

$ python exceptions_KeyError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_KeyError.py&amp;quot;, line 13, in &amp;lt;module&amp;gt;
    print d['c']
KeyError: 'c'
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;KeyboardInterrupt&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;KeyboardInterrupt&lt;/code&gt; ocurre cuando el usuario presiona Control-C (o Delete)
   para detener un programa en ejecución.  A diferencias de la mayoría de las
   excepciones, &lt;code&gt;KeyboardInterrupt&lt;/code&gt; se deriva directamente de &lt;code&gt;BaseException&lt;/code&gt; para
   evitar ser atrapada por gestores de excepción globales que atrapan &lt;code&gt;Exception&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try:
    print 'Presiona Return o Control-C:',
    ignored = raw_input()
except Exception, err:
    print 'Excepción atrapada:', err
except KeyboardInterrupt, err:
    print 'Excepción KeyboardInterrupt'
else:
    print 'Ninguna excepción'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Presionando Control-C en la consola ocasiona una excepción &lt;code&gt;KeyboardInterrupt&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python exceptions_KeyboardInterrupt.py
Presiona Return o Control-C: Excepción KeyboardInterrupt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;MemoryError&lt;/h4&gt;
&lt;p&gt;Si tu programa se queda sin memoria y es posible recuperarse (eliminando
   algunos objetos, por ejemplo), un &lt;code&gt;MemoryError&lt;/code&gt; es lanzado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import itertools

# Intenta crear un MemoryError asignando un montón de memoria
l = []
for i in range(3):
    try:
        for j in itertools.count(1):
            print i, j
            l.append('*' * (2**30))
    except MemoryError:
        print '(error, descartando la lista existente)'
        l = []

$ python exceptions_MemoryError.py
0 1
0 2
(error, descartando la lista existente)
1 1
1 2
(error, descartando la lista existente)
2 1
2 2
(error, descartando la lista existente)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NameError&lt;/h4&gt;
&lt;p&gt; &lt;code&gt;NameError&lt;/code&gt;s son lanzados cuando tu código hace referencia a un nombre que no
   existe en el ámbito (&lt;em&gt;scope&lt;/em&gt;) actual.  Por ejemplo, el nombre de una variable.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def func():
    print nombre_desconocido

func()

$ python exceptions_NameError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_NameError.py&amp;quot;, line 15, in &amp;lt;module&amp;gt;
    func()
  File &amp;quot;exceptions_NameError.py&amp;quot;, line 13, in func
    print nombre_desconocido
NameError: global name 'nombre_desconocido' is not defined
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NotImplementedError&lt;/h4&gt;
&lt;p&gt;Clases base definidas por el usuario pueden lanzar &lt;code&gt;NotImplementedError&lt;/code&gt; para
   indicar que un método o comportamiento tiene que ser definido por una sub
   clase, simulado así una interfaz.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class BaseClass(object):
    &amp;quot;&amp;quot;&amp;quot;Define la interfaz&amp;quot;&amp;quot;&amp;quot;
    def __init__(self):
        super(BaseClass, self).__init__()
    def do_something(self):
        &amp;quot;&amp;quot;&amp;quot;La interfaz, sin implementar&amp;quot;&amp;quot;&amp;quot;
        raise NotImplementedError(self.__class__.__name__ + '.do_something')

class SubClass(BaseClass):
    &amp;quot;&amp;quot;&amp;quot;Implementa la interfaz&amp;quot;&amp;quot;&amp;quot;
    def do_something(self):
        &amp;quot;&amp;quot;&amp;quot;hace algo de verdad&amp;quot;&amp;quot;&amp;quot;
        print self.__class__.__name__ + ' doing something!'

SubClass().do_something()
BaseClass().do_something()

$ python exceptions_NotImplementedError.py
SubClass haciendo algo!
Traceback (most recent call last):
  File &amp;quot;exceptions_NotImplementedError.py&amp;quot;, line 27, in &amp;lt;module&amp;gt;
    BaseClass().do_something()
  File &amp;quot;exceptions_NotImplementedError.py&amp;quot;, line 18, in do_something
    raise NotImplementedError(self.__class__.__name__ + '.do_something')
NotImplementedError: BaseClass.do_something
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OSError&lt;/h4&gt;
&lt;p&gt; &lt;code&gt;OSError&lt;/code&gt; sirve como la clase de error para el módulo os, y es lanzado cuando
   un error surge de una función específica del sistema operativo.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import os

for i in range(10):
    print i, os.ttyname(i)

$ python exceptions_OSError.py
0 /dev/pts/0
1 /dev/pts/0
2 /dev/pts/0
3
Traceback (most recent call last):
  File &amp;quot;exceptions_OSError.py&amp;quot;, line 15, in &amp;lt;module&amp;gt;
    print i, os.ttyname(i)
OSError: [Errno 9] Bad file descriptor
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OverflowError&lt;/h4&gt;
&lt;p&gt;Cuando una operación aritmética supera los límites del tipo de variable, un
   &lt;code&gt;OverflowError&lt;/code&gt; es lanzado.  Número enteros grandes asignan más espacio a
   medida que los valores crece, entonces terminan lanzando &lt;code&gt;MemoryError&lt;/code&gt;.  La
   gestión de excepciones de números de coma flotante no está estandarizada,
   entonces los números de coma flotante no se comprueban.  Número enteros
   normales son convertidos a valores &lt;code&gt;long&lt;/code&gt; según sea necesario.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import sys

print 'Número entereo normal: (maxint=%s)' % sys.maxint
try:
    i = sys.maxint * 3
    print 'Sin rebalse para ', type(i), 'i =', i
except OverflowError, err:
    print 'Rebalse en ', i, err

print
print 'Número entero largo:'
for i in range(0, 100, 10):
    print '%2d' % i, 2L ** i

print
print 'Valores de coma flotante:'
try:
    f = 2.0**i
    for i in range(100):
        print i, f
        f = f ** 2
except OverflowError, err:
    print 'Rebalse luego de ', f, err

$ python exceptions_OverflowError.py
Número entereo normal: (maxint=2147483647)
Sin rebalse para  &amp;lt;type 'long'&amp;gt; i = 6442450941

Número entero largo:
 0 1
10 1024
20 1048576
30 1073741824
40 1099511627776
50 1125899906842624
60 1152921504606846976
70 1180591620717411303424
80 1208925819614629174706176
90 1237940039285380274899124224

Valores de coma flotante:
0 1.23794003929e+27
1 1.53249554087e+54
2 2.34854258277e+108
3 5.5156522631e+216
Rebalse luego de  5.5156522631e+216 (34, 'Numerical result out of range')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ReferenceError&lt;/h4&gt;
&lt;p&gt;Cuando un &lt;em&gt;proxy&lt;/em&gt; &lt;code&gt;weakref&lt;/code&gt; es usado para acceder a un objeto que ya ha sido
   recolectado (&lt;em&gt;garbage collected&lt;/em&gt;), un &lt;code&gt;ReferenceError&lt;/code&gt; ocurre.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import gc
import weakref

class ExpensiveObject(object):
    def __init__(self, name):
        self.name = name
    def __del__(self):
        print '(Borrando %s)' % self

obj = ExpensiveObject('obj')
p = weakref.proxy(obj)

print 'ANTES:', p.name
obj = None
print 'DESPUÉS:', p.name

$ python exceptions_ReferenceError.py
ANTES: obj
(Borrando &amp;lt;__main__.ExpensiveObject object at 0xb7d1d64c&amp;gt;)
DESPUÉS:
Traceback (most recent call last):
  File &amp;quot;exceptions_ReferenceError.py&amp;quot;, line 26, in &amp;lt;module&amp;gt;
    print 'DESPUÉS:', p.name
ReferenceError: weakly-referenced object no longer exists
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;RuntimeError&lt;/h4&gt;
&lt;p&gt;Una excepción &lt;code&gt;RuntimeError&lt;/code&gt; es usada cuando ninguna otra excepción más
   específica es aplicable.  El intérprete no lanza esta excepción con mucha
   frecuencia, pero código de usuario lo hace.
&lt;/p&gt;

&lt;h4&gt;StopIteration&lt;/h4&gt;
&lt;p&gt;Cuando un iterador ha terminado, su método &lt;code&gt;next()&lt;/code&gt; lanza &lt;code&gt;StopIteration&lt;/code&gt;.
   Esta excepción no es considerada un error.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;l=[0,1,2]
i=iter(l)

print i
print i.next()
print i.next()
print i.next()
print i.next()

$ python exceptions_StopIteration.py
&amp;lt;listiterator object at 0xb7d6fb2c&amp;gt;
0
1
2
Traceback (most recent call last):
  File &amp;quot;exceptions_StopIteration.py&amp;quot;, line 19, in &amp;lt;module&amp;gt;
    print i.next()
StopIteration
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;SyntaxError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;SyntaxError&lt;/code&gt; ocurre cada vez que el analizador (&lt;em&gt;parser&lt;/em&gt;) encuentra código
   fuente que no entiende.  Esto puede ser al importar un módulo, invocando
   &lt;code&gt;exec&lt;/code&gt;, o invocando &lt;code&gt;eval()&lt;/code&gt;.  Los atributos de la excepción pueden ser usados
   para encontrar exactamente qué parte del texto de entrada ocasionó la
   excepción.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;try:
    print eval('cinco por tres')
except SyntaxError, err:
    print 'Error de sintaxis %s (%s-%s): %s' % \
        (err.filename, err.lineno, err.offset, err.text)
    print err

$ python exceptions_SyntaxError.py
Error de sintáxis &amp;lt;string&amp;gt; (1-9): cinco por tres
invalid syntax (&amp;lt;string&amp;gt;, line 1)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;SystemError&lt;/h4&gt;
&lt;p&gt;Cuando un error ocurre en el intérprete mismo y hay alguna oportunidad de
   continuar la ejecución con éxito, lanza un &lt;code&gt;SystemError&lt;/code&gt;.  &lt;code&gt;SystemError&lt;/code&gt;s
   probablemente indican una falla (&lt;em&gt;bug&lt;/em&gt;) en el intérprete y deberían ser
   reportados al mantenedor.
&lt;/p&gt;

&lt;h4&gt;SystemExit&lt;/h4&gt;
&lt;p&gt;Cuando &lt;code&gt;sys.exit()&lt;/code&gt; es invocada, lanza &lt;code&gt;SystemExit&lt;/code&gt; en lugar de salir
   inmediatamente.  Esto permite ejecutar código de limpieza en bloques
   &lt;code&gt;try:finally&lt;/code&gt; y a los que invocan el código (como depuradores y frameworks de
   prueba) capturar las excepciones y evitan salir.
&lt;/p&gt;

&lt;h4&gt;TypeError&lt;/h4&gt;
&lt;p&gt; &lt;code&gt;TypeErrors&lt;/code&gt; son ocasionados al combinar tipos equivocados de objetos o
   invocando una función con el tipo de objeto equivocado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;result = ('tupla',) + 'cadena'

$ python exceptions_TypeError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_TypeError.py&amp;quot;, line 12, in &amp;lt;module&amp;gt;
    result = ('tupla',) + 'cadena'
TypeError: can only concatenate tuple (not &amp;quot;str&amp;quot;) to tuple
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;UnboundLocalError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;UnboundLocalError&lt;/code&gt; es un tipo de &lt;code&gt;NameError&lt;/code&gt; específico para nombres de
   variables locales.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def throws_global_name_error():
    print unknown_global_name

def throws_unbound_local():
    local_val = local_val + 1
    print local_val

try:
    throws_global_name_error()
except NameError, err:
    print 'Error de nombre global:', err

try:
    throws_unbound_local()
except UnboundLocalError, err:
    print 'Error de nombre local:', err
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La diferencia entre el &lt;code&gt;NameError&lt;/code&gt; global y el &lt;code&gt;UnboundLocalError&lt;/code&gt; es la manera
   en que el nombre es usado.  Ya que el nombre &amp;quot;local_val&amp;quot; aparece en el lado
   izquierdo de una expresión, es interpretada como un nombre de variable local.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python exceptions_UnboundLocalError.py
Error de nombre global: global name 'unknown_global_name' is not defined
Error de nombre local: local variable 'local_val' referenced before assignment
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;UnicodeError&lt;/h4&gt;
&lt;p&gt; &lt;code&gt;UnicodeError&lt;/code&gt; es una sub clase de &lt;code&gt;ValueError&lt;/code&gt; y es lanzado cuando surge un
   problema con Unicode.  Hay clases sub clases separadas para
   &lt;code&gt;UnicodeEncodeError&lt;/code&gt;, &lt;code&gt;UnicodeDecodeError&lt;/code&gt;, y &lt;code&gt;UnicodeTranslateError&lt;/code&gt;.
&lt;/p&gt;

&lt;h4&gt;ValueError&lt;/h4&gt;
&lt;p&gt;Un &lt;code&gt;ValueError&lt;/code&gt; es usado cuando una función recibe un valor que tiene el tipo
   correcto pero un valor inválido.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print chr(1024)

$ python exceptions_ValueError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_ValueError.py&amp;quot;, line 12, in &amp;lt;module&amp;gt;
    print chr(1024)
ValueError: chr() arg not in range(256)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ZeroDivisionError&lt;/h4&gt;
&lt;p&gt;Cuando cero aparece en el denominador de una operación de división, un
   &lt;code&gt;ZeroDivisionError&lt;/code&gt; es lanzado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print 1/0

$ python exceptions_ZeroDivisionError.py
Traceback (most recent call last):
  File &amp;quot;exceptions_ZeroDivisionError.py&amp;quot;, line 12, in &amp;lt;module&amp;gt;
    print 1/0
ZeroDivisionError: integer division or modulo by zero
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Categorías de Warning&lt;/h3&gt;
&lt;p&gt;También hay varias excepciones definidas para ser usadas con el módulo
   &lt;a href="http://denklab.org/articles/2008/7/pymotw-warnings/pymotw-warnings/"&gt;warnings&lt;/a&gt;.
&lt;/p&gt;
&lt;dl&gt;
    &lt;dt&gt;Warning&lt;/dt&gt;
    &lt;dd&gt;La clase base para todas las advertencias (*warnings*).&lt;/dd&gt;
    &lt;dt&gt;UserWarning&lt;/dt&gt;
    &lt;dd&gt;Clase base para advertencias que surgen en código del usuario.&lt;/dd&gt;
    &lt;dt&gt;DeprecationWarning&lt;/dt&gt;
    &lt;dd&gt;Usada para características que ya no están siendo mantenidas.&lt;/dd&gt;
    &lt;dt&gt;PendingDeprecationWarning&lt;/dt&gt;
    &lt;dd&gt;Usada para características que van a ser obsoletas pronto.&lt;/dd&gt;
    &lt;dt&gt;SyntaxWarning&lt;/dt&gt;
    &lt;dd&gt;Usada para sintáxis dudosa.&lt;/dd&gt;
    &lt;dt&gt;RuntimeWarning&lt;/dt&gt;
    &lt;dd&gt;Usada para para eventos que suceden en la ejecución que pueden causar problemas.&lt;/dd&gt;
    &lt;dt&gt;FutureWarning&lt;/dt&gt;
    &lt;dd&gt;Advertencia sobre cambios al lenguaje o la biblioteca en el futuro.&lt;/dd&gt;
    &lt;dt&gt;ImportWarning&lt;/dt&gt;
    &lt;dd&gt;Advertencia sobre problemas al importar un módulo.&lt;/dd&gt;
    &lt;dt&gt;UnicodeWarning&lt;/dt&gt;
    &lt;dd&gt;Advertencia sobre problemas con texto unicode.&lt;/dd&gt;
&lt;/dl&gt;


&lt;h3&gt;Referencias&lt;/h3&gt;
&lt;p&gt; &lt;a href="http://docs.python.org/lib/module-exceptions.html"&gt;Documentación biblioteca estándar: exceptions&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt; &lt;a href="http://denklab.org/copyright/pymotw/"&gt;Copyright&lt;/a&gt; 2008 &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt; 
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/denklabpymotwarticles/~4/kdYbBpOnth4" height="1" width="1"/&gt;</description><pubDate>Sun, 21 Sep 2008 23:06:19 -0400</pubDate><guid isPermaLink="false">http://denklab.org/articles/2008/9/pymotw-exceptions/</guid><feedburner:origLink>http://denklab.org/articles/2008/9/pymotw-exceptions/</feedburner:origLink></item><item><title>PyMOTW: profile, cProfile, pstats
</title><link>http://feedproxy.google.com/~r/denklabpymotwarticles/~3/eapMqKMLxGI/</link><description>&lt;p&gt;Traducción de &lt;a href="http://blog.doughellmann.com/2008/08/pymotw-profile-cprofile-pstats.html"&gt;PyMOTW: profile, cProfile, pstats&lt;/a&gt; los módulos &lt;code&gt;profile&lt;/code&gt; y &lt;code&gt;cProfile&lt;/code&gt;de la columna semanal de &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;



&lt;hr noshade&gt;


&lt;p&gt;Los módulos &lt;code&gt;profile&lt;/code&gt; y &lt;code&gt;cProfile&lt;/code&gt; proporcionan interfaces de programación para
   coleccionar y analizar estadísticas sobre cómo código Python consume recursos de
   procesamiento.
&lt;/p&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Módulo:&lt;/th&gt;
        &lt;td&gt;&lt;a href="http://docs.python.org/lib/module-profile.html"&gt;profile&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Propósito:&lt;/th&gt;
        &lt;td&gt;Análisis de de rendimiento de programas en Python&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Versiones de Python:&lt;/td&gt;
        &lt;td&gt;1.4 y posterior, estos ejemplos son para Python 2.5&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;


&lt;h3&gt;run():&lt;/h3&gt;
&lt;p&gt;El punto más básico de inicio en el módulo &lt;code&gt;profile&lt;/code&gt; es &lt;code&gt;run()&lt;/code&gt;.  Acepta una
   cadena como argumento, y crea un reporte del tiempo empleado ejecutando diversas
   líneas de código mientras ejecuta la instrucción.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile

def fib(n):
    # de http://en.literateprograms.org/Fibonacci_numbers_(Python)
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

def fib_seq(n):
    seq = [ ]
    if n &amp;gt; 0:
        seq.extend(fib_seq(n-1))
    seq.append(fib(n))
    return seq

print 'RUDIMENTARIO'
print '=' * 80
profile.run('print fib_seq(20); print')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Esta versión recursiva de un calculador de una secuencia Fibonacci es
   especialmente útil para demostrar el módulo &lt;code&gt;profile&lt;/code&gt; porque podemos tanto
   mejorar el rendimiento.  El formato estándar del reporte muestra un sumario y
   detalles de cada función ejecutada.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_fibonacci_raw.py
RUDIMENTARIO
================================================================================
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

         57356 function calls (66 primitive calls) in 0.584 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       21    0.000    0.000    0.000    0.000 :0(append)
       20    0.000    0.000    0.000    0.000 :0(extend)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
        1    0.000    0.000    0.580    0.580 &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)
        1    0.004    0.004    0.584    0.584 profile:0(print fib_seq(20); print)
        0    0.000             0.000          profile:0(profiler)
 57291/21    0.580    0.000    0.580    0.028 profile_fibonacci_raw.py:13(fib)
     21/1    0.000    0.000    0.580    0.580 profile_fibonacci_raw.py:22(fib_seq)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Como puedes ver, la ejecución requiere de 57356 invocaciones de función y toma
   1/2 segundo.  Ya que hay tan solo 66 invocaciones &lt;em&gt;primitivas&lt;/em&gt;, sabemos que
   la gran mayoría de las 57 mil invocaciones fueron recursivas.  Los detalles
   sobre donde se pasó el tiempo están separados por función en el listado que
   muestra el numero de invocaciones, el tiempo total transcurrido en la función,
   el tiempo por invocación (&lt;code&gt;tottime/ncalls&lt;/code&gt;), tiempo acumulado transcurrido en
   una función y la relación de tiempo acumulado a invocaciones primitivas.
&lt;/p&gt;
&lt;p&gt;No es sorprendente que la mayoría del tiempo aquí transcurre invocando &lt;code&gt;fib()&lt;/code&gt;
   en repetidas ocasiones.  Podemos añadir un decorador &lt;code&gt;memoize&lt;/code&gt; para reducir el
   número de invocaciones recursivas y obtener un impacto importante en el
   rendimiento de esta función.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile

class memoize:
    # de http://avinashv.net/2008/04/python-decorators-syntactic-sugar/
    def __init__(self, function):
        self.function = function
        self.memoized = {}

    def __call__(self, *args):
        try:
            return self.memoized[args]
        except KeyError:
            self.memoized[args] = self.function(*args)
            return self.memoized[args]

@memoize
def fib(n):
    # de http://en.literateprograms.org/Fibonacci_numbers_(Python)
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

def fib_seq(n):
    seq = [ ]
    if n &amp;gt; 0:
        seq.extend(fib_seq(n-1))
    seq.append(fib(n))
    return seq

if __name__ == '__main__':
    print 'MEMOIZADO'
    print '=' * 80
    profile.run('print fib_seq(20); print')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Recordando el valor de (la serie) Fibonacci podemos evitar la mayoría de la
   recursión y reducir a 145 las invocaciones que tan sólo toman 0.008 segundos.
   También nota que el contador &lt;code&gt;ncalls&lt;/code&gt; para &lt;code&gt;fib()&lt;/code&gt; muestra que &lt;strong&gt;nunca&lt;/strong&gt; entra
   en recursión.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_fibonacci_memoized.py
MEMOIZADO
================================================================================
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

         145 function calls (87 primitive calls) in 0.008 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       21    0.000    0.000    0.000    0.000 :0(append)
       20    0.000    0.000    0.000    0.000 :0(extend)
        1    0.004    0.004    0.004    0.004 :0(setprofile)
        1    0.000    0.000    0.004    0.004 &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)
        1    0.000    0.000    0.008    0.008 profile:0(print fib_seq(20); print)
        0    0.000             0.000          profile:0(profiler)
    59/21    0.000    0.000    0.000    0.000 profile_fibonacci_memoized.py:19(__call__)
       21    0.000    0.000    0.000    0.000 profile_fibonacci_memoized.py:26(fib)
     21/1    0.004    0.000    0.004    0.004 profile_fibonacci_memoized.py:36(fib_seq)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;runctx():&lt;/h3&gt;
&lt;p&gt;Obviamente, no siempre es fácil construir la expresión para pasar a &lt;code&gt;run()&lt;/code&gt;.
   Algunas veces es más fácil construir una expresión simple y ejecutarla en un
   contexto con (variables) globales y locales, usando &lt;code&gt;runctx()&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile
from profile_fibonacci_memoized import fib, fib_seq

if __name__ == '__main__':
    profile.runctx('print fib_seq(n); print', globals(), {'n':20})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En este ejemplo, el valor de &amp;quot;n&amp;quot; es pasado mediante el contexto de variables
   locales en lugar de estar embebido directamente en la instrucción que se pasa a
   &lt;code&gt;runctx()&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_runctx.py
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]

         145 function calls (87 primitive calls) in 0.004 CPU seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       21    0.000    0.000    0.000    0.000 :0(append)
       20    0.000    0.000    0.000    0.000 :0(extend)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
        1    0.000    0.000    0.004    0.004 &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)
        1    0.000    0.000    0.004    0.004 profile:0(print fib_seq(n); print)
        0    0.000             0.000          profile:0(profiler)
    59/21    0.000    0.000    0.004    0.000 profile_fibonacci_memoized.py:19(__call__)
       21    0.004    0.000    0.004    0.000 profile_fibonacci_memoized.py:26(fib)
     21/1    0.000    0.000    0.004    0.004 profile_fibonacci_memoized.py:36(fib_seq)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt; &lt;code&gt;pstats&lt;/code&gt;: Guardando y trabajando con estadíticas:&lt;/h3&gt;
&lt;p&gt;Si el reporte estándar no está formateado de la manera que lo necesitas, ambos
   &lt;code&gt;run()&lt;/code&gt; y &lt;code&gt;runctx()&lt;/code&gt; aceptan un nombre de archivo como argumento para guardar
   los datos en un archivo en lugar de mostrar el reporte.  La clase &lt;code&gt;Stats&lt;/code&gt; del
   módulo &lt;code&gt;pstats&lt;/code&gt; sabe cómo leer el archivo y puede ser usada para manipular los
   datos.
&lt;/p&gt;
&lt;p&gt;Por ejemplo, para ejecutar varias veces el mismo test y combinar los
   resultados, puede hacer algo como esto:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile
import pstats
from profile_fibonacci_memoized import fib, fib_seq

# Crea 5 conjuntos de estadística
filenames = []
for i in range(5):
    filename = 'profile_stats_%d.stats' % i
    profile.run('print %d, fib_seq(20)' % i, filename)

# Lee los 5 archivos con estadísticas en un solo objeto 
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, 5):
    stats.add('profile_stats_%d.stats' % i)

# Limpia nombres de archivos para el reporte
stats.strip_dirs()

# Ordena las estadísticas por el tiempo acumulado en la función
stats.sort_stats('cumulative')

stats.print_stats()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;El reporte resultante está ordenado en orden descendiente de tiempo acumulado
   transcurrido en la función y los nombres de directorios son eliminados de los
   archivos mostrados para ahorra espacio horizontal.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_stats.py
0 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
1 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
2 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
3 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
4 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
Wed Sep  3 21:22:27 2008    profile_stats_0.stats
Wed Sep  3 21:22:27 2008    profile_stats_1.stats
Wed Sep  3 21:22:27 2008    profile_stats_2.stats
Wed Sep  3 21:22:27 2008    profile_stats_3.stats
Wed Sep  3 21:22:27 2008    profile_stats_4.stats

         489 function calls (351 primitive calls) in 0.032 CPU seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.004    0.001    0.024    0.005 &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)
    105/5    0.012    0.000    0.020    0.004 profile_fibonacci_memoized.py:36(fib_seq)
        1    0.000    0.000    0.012    0.012 profile:0(print 0, fib_seq(20))
  143/105    0.004    0.000    0.008    0.000 profile_fibonacci_memoized.py:19(__call__)
        1    0.004    0.004    0.008    0.008 profile:0(print 3, fib_seq(20))
        1    0.004    0.004    0.008    0.008 profile:0(print 1, fib_seq(20))
       21    0.004    0.000    0.004    0.000 profile_fibonacci_memoized.py:26(fib)
        1    0.000    0.000    0.004    0.004 profile:0(print 4, fib_seq(20))
      105    0.000    0.000    0.000    0.000 :0(append)
        5    0.000    0.000    0.000    0.000 :0(setprofile)
      100    0.000    0.000    0.000    0.000 :0(extend)
        1    0.000    0.000    0.000    0.000 profile:0(print 2, fib_seq(20))
        0    0.000             0.000          profile:0(profiler)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Limitando el contenido del reporte:&lt;/h3&gt;
&lt;p&gt;Ya que estamos estudiando el rendimiento de &lt;code&gt;fib()&lt;/code&gt; y &lt;code&gt;fib_seq()&lt;/code&gt;, podemos
   también restringir la salida del reporte para incluir estas funciones usando
   una expresión regular que coincida con los valores de
   &lt;code&gt;archivo:línea(función)&lt;/code&gt; que queremos.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile
import pstats
from profile_fibonacci_memoized import fib, fib_seq

# Lee los 5 archivos con estadísticas en un solo objeto
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, 5):
    stats.add('profile_stats_%d.stats' % i)
stats.strip_dirs()
stats.sort_stats('cumulative')

# Limita el resulato a líneas con &amp;quot;(fib&amp;quot;
stats.print_stats('\(fib')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La expresión regular incluye un paréntesis izquierdo literal (() para coincidir
   con la parte del nombre de la función del valor &lt;code&gt;location&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_stats_restricted.py
Wed Sep  3 21:22:27 2008    profile_stats_0.stats
Wed Sep  3 21:22:27 2008    profile_stats_1.stats
Wed Sep  3 21:22:27 2008    profile_stats_2.stats
Wed Sep  3 21:22:27 2008    profile_stats_3.stats
Wed Sep  3 21:22:27 2008    profile_stats_4.stats

         489 function calls (351 primitive calls) in 0.032 CPU seconds

   Ordered by: cumulative time
   List reduced from 13 to 2 due to restriction &amp;lt;'\\(fib'&amp;gt;

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    105/5    0.012    0.000    0.020    0.004 profile_fibonacci_memoized.py:36(fib_seq)
       21    0.004    0.000    0.004    0.000 profile_fibonacci_memoized.py:26(fib)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Grafos de funciones invocadas e invocadoras (&lt;em&gt;caller/callee&lt;/em&gt;):&lt;/h3&gt;
&lt;p&gt; &lt;code&gt;Stats&lt;/code&gt; también incluye métodos para mostrar las funciones invocadas y quienes
   las invocan.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import profile
import pstats
from profile_fibonacci_memoized import fib, fib_seq

# Lee los 5 archivos con estadísticas en un solo objeto
stats = pstats.Stats('profile_stats_0.stats')
for i in range(1, 5):
    stats.add('profile_stats_%d.stats' % i)
stats.strip_dirs()
stats.sort_stats('cumulative')

print 'INVOCACIONES ENTRANTES:'
stats.print_callers('\(fib')

print 'INVOCACIONES SALIENTES:'
stats.print_callees('\(fib')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Los argumentos de &lt;code&gt;print_callers()&lt;/code&gt; y &lt;code&gt;print_callees()&lt;/code&gt; funciona de la misma
   manera que los argumentos de restricción de &lt;code&gt;print_stats()&lt;/code&gt;.  El resultado
   muestra en invocador (&lt;em&gt;caller&lt;/em&gt;), el invocado (&lt;em&gt;callee&lt;/em&gt;) y el tiempo acumulado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python profile_stats_callers.py
INVOCACIONES ENTRANTES:
   Ordered by: cumulative time
   List reduced from 13 to 2 due to restriction &amp;lt;'\\(fib'&amp;gt;

Function                                   was called by...
profile_fibonacci_memoized.py:36(fib_seq)  &amp;lt;- &amp;lt;string&amp;gt;:1(&amp;lt;module&amp;gt;)(5)    0.024
                                              profile_fibonacci_memoized.py:36(fib_seq)(100)    0.020
profile_fibonacci_memoized.py:26(fib)      &amp;lt;- profile_fibonacci_memoized.py:19(__call__)(21)    0.008


INVOCACIONES SALIENTES:
   Ordered by: cumulative time
   List reduced from 13 to 2 due to restriction &amp;lt;'\\(fib'&amp;gt;

Function                                   called...
profile_fibonacci_memoized.py:36(fib_seq)  -&amp;gt; :0(append)(105)    0.000
                                              :0(extend)(100)    0.000
                                              profile_fibonacci_memoized.py:19(__call__)(105)    0.008
                                              profile_fibonacci_memoized.py:36(fib_seq)(100)    0.020
profile_fibonacci_memoized.py:26(fib)      -&amp;gt; profile_fibonacci_memoized.py:19(__call__)(38)    0.008
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Referencias:&lt;/h3&gt;
&lt;p&gt; &lt;a href="http://www.doughellmann.com/PyMOTW/"&gt;Python Module of the Week Home&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://www.doughellmann.com/downloads/PyMOTW-1.67.1.tar.gz"&gt;Descarga el código&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://docs.python.org/lib/module-profile.html"&gt;profile y cProfile&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://docs.python.org/lib/profile-stats.html"&gt;pstats&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;La implementación del ejemplo Fibonacci es de &lt;a href="http://en.literateprograms.org/Fibonacci_numbers_(Python"&gt;Fibonacci numbers (Python) - LiteratePrograms&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;El decorador &lt;code&gt;memoize&lt;/code&gt; es de &lt;a href="http://avinashv.net/2008/04/python-decorators-syntactic-sugar/"&gt;Python Decorators: Syntactic Sugar | avinash.vora&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt; &lt;a href="http://denklab.org/copyright/pymotw/"&gt;Copyright&lt;/a&gt; 2008 &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/denklabpymotwarticles/~4/eapMqKMLxGI" height="1" width="1"/&gt;</description><pubDate>Wed, 03 Sep 2008 21:52:50 -0400</pubDate><guid isPermaLink="false">http://denklab.org/articles/2008/9/pymotw-profile-cprofile-pstats/</guid><feedburner:origLink>http://denklab.org/articles/2008/9/pymotw-profile-cprofile-pstats/</feedburner:origLink></item><item><title>PyMOTW: signal
</title><link>http://feedproxy.google.com/~r/denklabpymotwarticles/~3/8npI2gpqxm4/</link><description>&lt;p&gt;Traducción de &lt;a href="http://blog.doughellmann.com/2008/08/pymotw-signal.html"&gt;PyMOTW: signal&lt;/a&gt; el módulo
   &lt;code&gt;signal&lt;/code&gt; de la columna semanal de &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;



&lt;hr noshade&gt;


&lt;p&gt;Recibe notificaciones de eventos asíncronos del sistema con el módulo &lt;code&gt;signal&lt;/code&gt;.
&lt;/p&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Módulo:&lt;/th&gt;
        &lt;td&gt;&lt;a href="http://docs.python.org/lib/module-signal.html"&gt;signal&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Propósito:&lt;/th&gt;
        &lt;td&gt;Manejar eventos asíncronos.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Versión de Python:&lt;/th&gt;
        &lt;td&gt;1.4 y posterior&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;


&lt;h3&gt;Descripción:&lt;/h3&gt;
&lt;p&gt; &lt;em&gt;Programar con manipuladores de señales Unix es un esfuerzo nada trivial.  Ésta
es una introducción y no incluye todos los detalles que puedes necesitar para
usar exitosamente señales en cualquier plataforma.  Hay una cierta
estandarización en las versiones de Unix, pero también hay también algunas
diferencias, así que consulta la documentación de tu sistema operativo si
tienes problemas.&lt;/em&gt; 
&lt;/p&gt;
&lt;p&gt;Señales son medios para notificar a tu programa de un evento, y manipularlo
   asíncronamente.  Pueden ser generadas por el mismo sistema, o enviadas desde
   un proceso a otro, es posible que algunas operaciones (especialmente de
   entrada/salida, &lt;em&gt;I/O&lt;/em&gt;) puedan producir errores si reciben una señal en el medio
   (de su ejecución).
&lt;/p&gt;
&lt;p&gt;Las señales están identificadas por número enteros y son definidas en los
   encabezados C del sistema operativo.  Python define las señales apropiadas para
   la plataforma como símbolos en el módulo &lt;code&gt;signal&lt;/code&gt;.  En los ejemplos a
   continuación, voy a usar &lt;code&gt;SIGINT&lt;/code&gt; y &lt;code&gt;SIGUSR1&lt;/code&gt;.  Ambas están normalmente
   definidas para todos lo sistemas Unix y similares a Unix.
&lt;/p&gt;

&lt;h3&gt;Recibiendo señales:&lt;/h3&gt;
&lt;p&gt;Como con otras formas de programación basada en eventos, las señales se reciben
   estableciendo una función de retorno (&lt;em&gt;callback&lt;/em&gt;), invocada por el manipulador
   de la señal, que es invocada cuando la señal ocurre.  Los argumentos para tu
   manipulador de señal son el número de la señal y el marco de la pila (&lt;em&gt;stack
frame&lt;/em&gt;) del punto en tu programa que fue interrumpido por la señal.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal
import os
import time

def receive_signal(signum, stack):
    print 'Recibida', signum

signal.signal(signal.SIGUSR1, receive_signal)
signal.signal(signal.SIGUSR2, receive_signal)

print 'Mi PID es:', os.getpid()

while True:
    print 'Esperando...'
    time.sleep(3)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Este ejemplo relativamente simple repite el bucle indefinidamente, pausando por
   unos cuantos segundos cada vez.  Cuando una señal llega, la invocación de
   &lt;code&gt;sleep&lt;/code&gt; es interrumpida y el manipulador de la señal &lt;code&gt;receive_signal()&lt;/code&gt; muestra
   el número de la señal.  Cuando el manipulador de la señal retorna, el bucle
   continua.
&lt;/p&gt;
&lt;p&gt;Para enviar señales a programas en ejecución, yo uso el programa de línea de
   comandos &lt;code&gt;kill&lt;/code&gt;.  Para producir el resultado a continuación, ejecuto
   &lt;code&gt;signal_signal.py&lt;/code&gt; en una ventana, luego &lt;code&gt;kill -USR1 7810&lt;/code&gt;, &lt;code&gt;kill -USR2 7810&lt;/code&gt; y
   &lt;code&gt;kill -INT 7810&lt;/code&gt; en otra.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_signal.py 
Mi PID es: 7810
Esperando...
Esperando...
Recibida 10
Esperando...
Esperando...
Recibida 12
Esperando...
Esperando...
Traceback (most recent call last):
  File &amp;quot;signal_signal.py&amp;quot;, line 25, in &amp;lt;module&amp;gt;
    time.sleep(3)
KeyboardInterrupt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt; &lt;code&gt;getsignal()&lt;/code&gt;:&lt;/h3&gt;
&lt;p&gt;Para ver qué manipulador están registrados para una señal, usa &lt;code&gt;getsignal()&lt;/code&gt;.
   Pasa el número de la señal como argumento.  El valor de retorno es el
   manipulador registrado, o uno de los valores especiales &lt;code&gt;signa.SIG_IGN&lt;/code&gt; (si la
   señal está siendo ignorada), &lt;code&gt;signal.SIG_DFL&lt;/code&gt; (si el comportamiento por defecto
   es usado), o &lt;code&gt;None&lt;/code&gt; (si el manipulador existente de la señal fue registrado
   desde C, en lugar de Python).
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal

def alarm_received(n, stack):
    return

signal.signal(signal.SIGALRM, alarm_received)

signals_to_names = {}
for n in dir(signal):
    if n.startswith('SIG') and not n.startswith('SIG_'):
        signals_to_names[getattr(signal, n)] = n

for s, name in sorted(signals_to_names.items()):
    handler = signal.getsignal(s)
    if handler is signal.SIG_DFL:
        handler = 'SIG_DFL'
    elif handler is signal.SIG_IGN:
        handler = 'SIG_IGN'
    print '%-10s (%2d):' % (name, s), handler
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Una vez más, ya que cada sistema operativo define distintas señales, el
   resultado que ves ejecutando ésto en otros sistemas puede variar.  Ésto es
   Linux:
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_getsignal.py
SIGHUP     ( 1): SIG_DFL
SIGINT     ( 2): &amp;lt;built-in function default_int_handler&amp;gt;
SIGQUIT    ( 3): SIG_DFL
SIGILL     ( 4): SIG_DFL
SIGTRAP    ( 5): SIG_DFL
SIGIOT     ( 6): SIG_DFL
SIGBUS     ( 7): SIG_DFL
SIGFPE     ( 8): SIG_DFL
SIGKILL    ( 9): SIG_DFL
SIGUSR1    (10): SIG_DFL
SIGSEGV    (11): SIG_DFL
SIGUSR2    (12): SIG_DFL
SIGPIPE    (13): SIG_IGN
SIGALRM    (14): &amp;lt;function alarm_received at 0xb7dd2fb4&amp;gt;
SIGTERM    (15): SIG_DFL
SIGCLD     (17): SIG_DFL
SIGCONT    (18): SIG_DFL
SIGSTOP    (19): SIG_DFL
SIGTSTP    (20): SIG_DFL
SIGTTIN    (21): SIG_DFL
SIGTTOU    (22): SIG_DFL
SIGURG     (23): SIG_DFL
SIGXCPU    (24): SIG_DFL
SIGXFSZ    (25): SIG_IGN
SIGVTALRM  (26): SIG_DFL
SIGPROF    (27): SIG_DFL
SIGWINCH   (28): SIG_DFL
SIGPOLL    (29): SIG_DFL
SIGPWR     (30): SIG_DFL
SIGSYS     (31): SIG_DFL
SIGRTMIN   (34): SIG_DFL
SIGRTMAX   (64): SIG_DFL
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Enviando señales:&lt;/h3&gt;
&lt;p&gt;La función para enviar señales es &lt;code&gt;os.kill()&lt;/code&gt;.  Su uso está descrito en el
   &lt;a href="http://www.doughellmann.com/PyMOTW/os/os.html#creating-processes-with-os-fork"&gt;artículo PyMOTW que describe el módulo
os&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;(La traducción del artículo sobre el módulo &lt;code&gt;os&lt;/code&gt; estará disponible pronto.)
&lt;/p&gt;

&lt;h3&gt;Alarmas:&lt;/h3&gt;
&lt;p&gt;Alarmas son una clase algo especial de señales, donde tu programa le pide al
   sistema operativo que lo notifique después de que un período de tiempo ha
   transcurrido.  Como la documentación estándar del módulo
   &lt;a href="http://docs.python.org/lib/node545.html"&gt;señala&lt;/a&gt;, ésto es útil para evitar
   bloquearse indefinidamente en una operación de entrada/salida (&lt;em&gt;I/O&lt;/em&gt;) u otra
   operación del sistema operativo.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal
import time

def receive_alarm(signum, stack):
    print 'Alarma  :', time.ctime()

# Invoca receive_alarm luego de 2 segundos
signal.signal(signal.SIGALRM, receive_alarm)
signal.alarm(2)

print 'Antes   :', time.ctime()
time.sleep(4)
print 'Después :', time.ctime()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;En este ejemplo, la invocación de &lt;code&gt;sleep()&lt;/code&gt; no dura los 4 segundos completos.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_alarm.py
Antes   : Tue Aug 19 10:53:19 2008
Alarma  : Tue Aug 19 10:53:21 2008
Después : Tue Aug 19 10:53:21 2008
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ignorando Señales:&lt;/h3&gt;
&lt;p&gt;Para ignorar una señal, registra &lt;code&gt;SIG_IGN&lt;/code&gt; como el manipulador.  Este script
   remplaza el manipulador por defecto para &lt;code&gt;SIGINT&lt;/code&gt; con &lt;code&gt;SIG_IGN&lt;/code&gt;, y registra un
   manipulador para &lt;code&gt;SIGUSR1&lt;/code&gt;.  Luego usa &lt;code&gt;signal.pause()&lt;/code&gt; para esperar una señal.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal
import os
import time

def do_exit(sig, stack):
    raise SystemExit('Saliendo')

signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGUSR1, do_exit)

print 'Mi PID:', os.getpid()

signal.pause()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Normalmente &lt;code&gt;SIGINT&lt;/code&gt; (la señal enviada por la línea de comandos a tu programa
   cuando presionas Control-C) eleva &lt;code&gt;KeyboardInterrupt&lt;/code&gt;.  En este caso, ignoramos
   &lt;code&gt;SIGINT&lt;/code&gt; y elevamos &lt;code&gt;SystemExit&lt;/code&gt; cuando vemos &lt;code&gt;SIGUSR1&lt;/code&gt;.  Cada ^C representa un
   intento de usar Control-C para terminar el script desde la terminal.  Usando
   kill -USR1 7820 desde otra terminal ocasiona que el script finalice.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_ignore.py 
My PID: 7820
^C^C^CSaliendo
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Señales e hilos de ejecución (&lt;em&gt;threads&lt;/em&gt;):&lt;/h3&gt;
&lt;p&gt;Generalmente señales e hilos de ejecución no combinan bien.  Sólo el hilo
   principal de ejecución de un proceso recibe señales, entonces generalmente no
   es útil usarlas en hilos de ejecución.  El siguiente ejemplo de un manipulador
   de señales espera por una señal en un hilo de ejecución, y envía la señal desde
   otro.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal
import threading
import os
import time

def signal_handler(num, stack):
    print 'Recibe señal %d en %s' % (num, threading.currentThread())

signal.signal(signal.SIGUSR1, signal_handler)

def wait_for_signal():
    print 'Esperando por señal en', threading.currentThread()
    signal.pause()
    print 'Dejando de esperar'

# Inicia un hilo que no recibirá la señal
receiver = threading.Thread(target=wait_for_signal, name='receiver')
receiver.start()
time.sleep(0.1)

def send_signal():
    print 'Enviando señal en', threading.currentThread()
    os.kill(os.getpid(), signal.SIGUSR1)

sender = threading.Thread(target=send_signal, name='sender')
sender.start()
sender.join()

# Espera que el hilo vea la señal (no va a suceder!)
print 'Esperando por', receiver
signal.alarm(2)
receiver.join()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nota que todos los manipuladores de señal fueron registrados en el hilo
   principal.  Este es un requerimiento de la implementación del módulo &lt;code&gt;signal&lt;/code&gt;
   para Python, sin importar el soporte subyacente de plataforma mezclar hilos de
   ejecución y señales.  Aunque el hilo receptor invoca &lt;code&gt;signal.pause()&lt;/code&gt;, no
   recibe la señal.  La invocación &lt;code&gt;signal.alarm(2)&lt;/code&gt; cerca al final del ejemplo
   evita un bloqueo sin fin, ya que el hilo receptor nunca terminará.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_threads.py 
Esperando por señal en &amp;lt;Thread(receiver, started)&amp;gt;
Enviando señal en &amp;lt;Thread(sender, started)&amp;gt;
Recibe señal 10 en &amp;lt;_MainThread(MainThread, started)&amp;gt;
Esperando por &amp;lt;Thread(receiver, started)&amp;gt;
Alarm clock
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Si bien se puede definir alarmas en hilos de ejecución, también son recibidas
   por el hilo principal.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import signal
import time
import threading

def signal_handler(num, stack):
    print time.ctime(), 'Alarma en', threading.currentThread()

signal.signal(signal.SIGALRM, signal_handler)

def use_alarm():
    print time.ctime(), 'Ajustando alarma en', threading.currentThread()
    signal.alarm(1)
    print time.ctime(), 'Durmiendo en', threading.currentThread()
    time.sleep(3)
    print time.ctime(), 'Dejando de dormir'

# Inicia un hilo que no recibirá la señal
alarm_thread = threading.Thread(target=use_alarm, name='alarm_thread')
alarm_thread.start()
time.sleep(0.1)

# Espera que el hilo vea la señal (no va a suceder!)
print time.ctime(), 'Esperando por', alarm_thread
alarm_thread.join()

print time.ctime(), 'Saliendo normalmente'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Nota que la alarma no aborta la invocación de &lt;code&gt;sleep()&lt;/code&gt; en &lt;code&gt;use_alarm()&lt;/code&gt;.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ python signal_threads_alarm.py
Tue Aug 19 11:49:47 2008 Ajustando alarma en &amp;lt;Thread(alarm_thread, started)&amp;gt;
Tue Aug 19 11:49:47 2008 Durmiendo en &amp;lt;Thread(alarm_thread, started)&amp;gt;
Tue Aug 19 11:49:47 2008 Esperando por &amp;lt;Thread(alarm_thread, started)&amp;gt;
Tue Aug 19 11:49:50 2008 Dejando de dormir
Tue Aug 19 11:49:50 2008 Alarma en &amp;lt;_MainThread(MainThread, started)&amp;gt;
Tue Aug 19 11:49:50 2008 Saliendo normalmente
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Referencias:&lt;/h3&gt;
&lt;p&gt; &lt;a href="http://www.doughellmann.com/PyMOTW/"&gt;Python Module of the Week Home&lt;/a&gt; &lt;br&gt;
   &lt;a href="http://www.doughellmann.com/downloads/PyMOTW-1.66.1.tar.gz"&gt;Descarga el código&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt; &lt;a href="http://denklab.org/copyright/pymotw/"&gt;Copyright&lt;/a&gt; 2008 &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/denklabpymotwarticles/~4/8npI2gpqxm4" height="1" width="1"/&gt;</description><pubDate>Tue, 19 Aug 2008 13:01:15 -0400</pubDate><guid isPermaLink="false">http://denklab.org/articles/2008/8/pymotw-signal/</guid><feedburner:origLink>http://denklab.org/articles/2008/8/pymotw-signal/</feedburner:origLink></item><item><title>PyMOTW: platform
</title><link>http://feedproxy.google.com/~r/denklabpymotwarticles/~3/M031NMNywZE/</link><description>&lt;p&gt;Traducción de &lt;a href="http://blog.doughellmann.com/2008/06/pymotw-platform.html"&gt;PyMOTW: platform&lt;/a&gt; el módulo
   &lt;code&gt;platform&lt;/code&gt; de la columna semanal de &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt;.
&lt;/p&gt;



&lt;hr noshade&gt;


&lt;p&gt;Prueba la arquitectura de una plataforma e infórmate de versiones con el módulo &lt;code&gt;platform&lt;/code&gt;.
&lt;/p&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;th&gt;Módulo:&lt;/th&gt;
        &lt;td&gt;&lt;a href="http://docs.python.org/lib/module-platform.html"&gt;platform&lt;/a&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Proposito:&lt;/th&gt;
        &lt;td&gt;Acceder a información sobre las versiones del hardware, el sistema operativo y el intérprete.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;th&gt;Versión de Python&lt;/th&gt;
        &lt;td&gt;2.3 y posterior&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;


&lt;h3&gt;Descripción:&lt;/h3&gt;
&lt;p&gt;A pesar de que Python es usado como un lenguaje multi-plataforma,
   ocasionalmente es necesario saber qué clase de sistema estás usando.
   Herramientas de compilación obviamente necesitan esta información, pero también
   sabrás que algunas librerías o comandos externos tienen distintas interfaces en
   distintos sistemas operativos.  Por ejemplo, si estás escribiendo una
   herramienta que gestione la configuración de red de un sistema operativo,
   puedes tener una representación portable de las interfaces de red, aliases,
   direcciones IP, etc.  Peto una vez que estés realmente editando los archivos de
   configuración, necesitas saber más acerca del sistema anfitrión y cómo está
   configurado.  El módulo &lt;code&gt;platform&lt;/code&gt; te da algunas herramientas para aprender
   acerca del intérprete, el sistema operativo y la plataforma de hardware que
   está ejecutando tu programa.
&lt;/p&gt;

&lt;h3&gt;Ejemplos:&lt;/h3&gt;
&lt;p&gt;Los resultados de los ejemplos a continuación han sido generados en una MacBook
   Pro corriendo OS X 10.5.2, una VAIO corriendo Ubuntu Linux 7.10 y Windows
   Vista.
&lt;/p&gt;
&lt;p&gt;(El artículo original de Doug Hellmann muestra los resultados de los ejemplos
   ejecutados en la MacBook mencionada y una instancia de WMWare corriendo CentOS
   4.6.)
&lt;/p&gt;

&lt;h3&gt;Intérprete:&lt;/h3&gt;
&lt;p&gt;Existen cuatro funciones para obtener información sobre el intérprete actual de
   Python.  &lt;code&gt;python_version()&lt;/code&gt; y &lt;code&gt;python_version_tuple()&lt;/code&gt; devuelven de forma
   distinta la versión del intérprete con componentes mayor (&lt;code&gt;major&lt;/code&gt;), menor
   (&lt;code&gt;minor&lt;/code&gt;) y parche (&lt;code&gt;patchlevel&lt;/code&gt;).  &lt;code&gt;python_compiler()&lt;/code&gt; reporta el compilador
   usado para crear el intérprete.  Y &lt;code&gt;python_build()&lt;/code&gt; da una cadena con la
   versión de compilación del intérprete.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import platform

print 'Version      :', platform.python_version()
print 'Version tuple:', platform.python_version_tuple()
print 'Compiler     :', platform.python_compiler()
print 'Build        :', platform.python_build()
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OS X:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_python.py
Version      : 2.5.1
Version tuple: ['2', '5', '1']
Compiler     : GCC 4.0.1 (Apple Computer, Inc. build 5367)
Build        : ('r251:54869', 'Apr 18 2007 22:08:04')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Linux:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_python.py 
Version      : 2.5.1
Version tuple: ['2', '5', '1']
Compiler     : GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
Build        : ('r251:54863', 'Jul 31 2008 23:17:40')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Windows Vista:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; python.exe platform_python.py
Version      : 2.5.2
Version tuple: ['2', '5', '2']
Compiler     : MSC v.1310 32 bit (Intel)
Build        : ('r252:60911', 'Feb 21 2008 13:11:45')
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Plataforma:&lt;/h3&gt;
&lt;p&gt;Un identificador de propósito general está disponible a través de la función
   &lt;code&gt;platform()&lt;/code&gt;.  &lt;code&gt;platform()&lt;/code&gt; acepta dos argumentos binarios opcionales.  Si
   &lt;code&gt;aliased&lt;/code&gt; es &lt;code&gt;True&lt;/code&gt;, los nombres en el valor de retorno son convertidos de un
   nombre formal a su forma más común.  Cuando &lt;code&gt;terse&lt;/code&gt; es &lt;code&gt;True&lt;/code&gt;, la función
   devuelve un valor mínimo con algunas partes recortadas.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import platform

print 'Normal :', platform.platform()
print 'Aliased:', platform.platform(aliased=True)
print 'Terse  :', platform.platform(terse=True)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OS X:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_platform.py
Normal : Darwin-9.2.2-i386-32bit
Aliased: Darwin-9.2.2-i386-32bit
Terse  : Darwin-9.2.2
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Linux:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_platform.py 
Normal : Linux-2.6.22-15-generic-i686-with-debian-lenny-sid
Aliased: Linux-2.6.22-15-generic-i686-with-debian-lenny-sid
Terse  : Linux-2.6.22-15-generic-i686-with-glibc2.4
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Windows Vista:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; python.exe platform_platform.py
Normal : Windows-Vista-6.0.6001
Aliased: Windows-Vista-6.0.6001
Terse  : Windows-Vista
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Información sobre el sistema operativo y el hardware:&lt;/h3&gt;
&lt;p&gt;Información más detallada sobre el sistema operativo y el hardware en el que se
   está ejecutando el intérprete puede ser obtenida también.  &lt;code&gt;uname()&lt;/code&gt; devuelve
   una tupla que contiene valores  del sistema (operativo), el nodo, el &lt;em&gt;release&lt;/em&gt;,
   la versión, la máquina y el procesador.  Se puede acceder a valores
   individuales a través de funciones con los mismos nombres:
&lt;/p&gt;
&lt;p&gt; &lt;code&gt;system()&lt;/code&gt; devuelve el nombre del sistema operativo. &lt;code&gt;node()&lt;/code&gt; devuelve el
   nombre del nodo, sin calificación completa.  &lt;code&gt;release()&lt;/code&gt; devuelve el número de
   &lt;em&gt;release&lt;/em&gt; del sistema operativo.  &lt;code&gt;version()&lt;/code&gt; devuelve el número versión más
   detallada del sistema.  &lt;code&gt;machine()&lt;/code&gt; da un identificador del tipo de hardware
   como 'i386'.  &lt;code&gt;processor()&lt;/code&gt; devuelve un identificador real para el procesador,
   o el mismo valor que &lt;code&gt;machine()&lt;/code&gt; en muchos casos.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import platform

print 'uname:', platform.uname()

print
print 'system   :', platform.system()
print 'node     :', platform.node()
print 'release  :', platform.release()
print 'version  :', platform.version()
print 'machine  :', platform.machine()
print 'processor:', platform.processor()
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OS X:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_os_info.py
uname: ('Darwin', 'farnsworth.local', '9.2.2', 'Darwin Kernel Version 9.2.2: Tue Mar  4 21:17:34 PST 2008; root:xnu-1228.4.31~1/RELEASE_I386', 'i386', 'i386')

system   : Darwin
node     : farnsworth.local
release  : 9.2.2
version  : Darwin Kernel Version 9.2.2: Tue Mar  4 21:17:34 PST 2008; root:xnu-1228.4.31~1/RELEASE_I386
machine  : i386
processor: i386
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Linux:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_os_info.py 
uname: ('Linux', 'notizbuch', '2.6.22-15-generic', '#1 SMP Fri Jul 11 19:25:33 UTC 2008', 'i686', '')

system   : Linux
node     : notizbuch
release  : 2.6.22-15-generic
version  : #1 SMP Fri Jul 11 19:25:33 UTC 2008
machine  : i686
processor:
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Windows Vista:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; python.exe platform_os_info.py
uname: ('Windows', 'Klapprechner', 'Vista', '6.0.6001', '', '')

system   : Windows
node     : Klapprechner
release  : Vista
version  : 6.0.6001
machine  :
processor:
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Arquitectura ejecutable:&lt;/h3&gt;
&lt;p&gt;Información individual sobre la arquitectura de un programa se puede obtener
   usando la función &lt;code&gt;architecture()&lt;/code&gt;.  El primer argumento el la ruta de un
   programa ejecutable (por defecto es &lt;code&gt;sys.executable&lt;/code&gt;, el intérprete de Python).
   El valor de retorno es una tupla que contiene la arquitectura de bits y el
   formato de &lt;em&gt;linkage&lt;/em&gt; usado.
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import platform

print 'interpreter:', platform.architecture()
print '/bin/ls    :', platform.architecture('/bin/ls')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;OS X:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_architecture.py
interpreter: ('32bit', '')
/bin/ls    : ('32bit', '')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Linux:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ python platform_architecture.py 
interpreter: ('32bit', '')
/bin/ls    : ('32bit', 'ELF')
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Windows Vista:&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; python.exe platform_architecture.py
interpreter: ('32bit', 'WindowsPE')
/bin/ls    : ('32bit', '')
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Referencias:&lt;/h3&gt;
&lt;p&gt; &lt;a href="http://www.doughellmann.com/projects/PyMOTW/"&gt;Python Module of the Week Home&lt;/a&gt;
   &lt;a href="http://www.doughellmann.com/downloads/PyMOTW-1.58.tar.gz"&gt;Descarga el código&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt; &lt;a href="/copyright/pymotw/"&gt;Copyright&lt;/a&gt; 2008 &lt;a href="http://www.doughellmann.com"&gt;Doug Hellmann&lt;/a&gt; 
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/denklabpymotwarticles/~4/M031NMNywZE" height="1" width="1"/&gt;</description><pubDate>Tue, 12 Aug 2008 21:56:04 -0400</pubDate><guid isPermaLink="false">http://denklab.org/articles/2008/8/pymotw-platform/</guid><feedburner:origLink>http://denklab.org/articles/2008/8/pymotw-platform/</feedburner:origLink></item></channel></rss>
