Palavras-chave: debug, depuração, trace, decorators
Essa dica veio de um amigo meu (Ulysses) e foi enviada para a lista de discussões PythonBrasil.
É muito comum precisar rastrear as chamadas de funções que ocorrem dentro dos programas, para facilitar nossa vida quando precisamos encontrar onde um determinado problema está ocorrendo. Ao mesmo tempo é muito chato ficar colocando e removendo código nos métodos para imprimir informações sobre os parâmetros recebidos e valores retornados por elas.
Nesta dica fizemos uso de uma das funcionalidades que Python disponibiliza que se chama decorator. O exemplo cria um decorator que retorna uma versão “envelopada” da nossa função original, que imprime seus dados de entrada e saída. Ele também faz uso da variável __debug__ para remover esse “envelope” quando o nosso programa for executado com a opção “-O“, evitando assim qualquer eventual perda de performance no seu programa.
def debugMethod(m): def w(*args,**kwargs): print "DBG: CALL Classe: %s Metodo: %s args: %s kwargs: %s" % ( args[0].__class__.__name__, m.__name__, args[1:], kwargs ) r = m(*args,**kwargs) print "DBG: RET return:", r return r if __debug__: return w return m
Para usar é supersimples:
class A(object): @debugMethod def teste(self, *arg, **kwargs): return (arg, kwargs) a = A() a.teste("foo", "bar", baz="qux")
O resultado final fica assim:
$ python teste.py DBG: CALL Classe: A Metodo: teste args: ('foo', 'bar') kwargs: {'baz': 'qux'} DBG: RET return: (('foo', 'bar'), {'baz': 'qux'}) $ python -O x.py $