2012-01-13 9 views
8

Quiero hacer un decorador que atrape las excepciones y las logre adecuadamente.extrañeza con un decorador

def logger(foo): 
    try: 
     print foo() 
    except Exception as e: 
     print e 

@logger 
def d(): 
    return 2/2 

if __name__ == '__main__': 
    d() 

que correcto lo piense, pero luego ejecutarlo y tengo una excepción de esta manera:

1 

Traceback (most recent call last): 

    File "log.py", line 14, in <module> 

    d() 

TypeError: 'NoneType' object is not callable 

Por qué intérprete me dice que la función tiene el tipo Ninguno, pero llamarlo y respuestas de impresión?

+0

Considere leer [Wiki en decoradores] (http://wiki.python.org/moin/PythonDecorators), [PEP-0318] (http://www.python.org/dev/peps/pep-0318/) y finalmente [esto] (http://docs.python.org/library/functools.html#functools.update_wrapper) – reclosedev

Respuesta

13

Su decorador necesita devolver una función, pero no devuelve nada, por lo tanto, el objeto 'TypeError:' NoneType 'no se puede llamar'. Se puede implementar de esta manera:

def logger(foo): 
    def fn(): 
     try: 
      print foo() 
     except Exception as e: 
      print e 
    return fn 

Salida This question para un buen ejemplo de cómo escribir/usar un decorador.

2

logger como lo ha definido, no devuelve ningún valor. Se puede pensar que todas estas funciones devuelven None. No ha definido su decorador correctamente. Debe tener un aspecto de la misma familia:

def logger(foo): 
    def _logger(foo): 
     try: 
      print foo() 
     except Exception as e: 
      print e 
    return _logger 

... pero ten en cuenta que este pierde una gran cantidad de información, capturas y se traga una gran cantidad de excepciones, y también se traga cualquier valor de retorno de la función de modo foo decorado. Si bien probablemente haga algo diferente en su código de producción de lo que ha mostrado aquí, lo importante es que la función de decorador debe devolver una función que se puede llamar (_logger en mi ejemplo).

Cuestiones relacionadas