Python: Rastreando chamadas de funções

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
$
This entry was posted in Python. Bookmark the permalink.