2

What is the easiest way to record function calls for debugging in Python? I'm usually interested in particular functions or all functions from a given class. Or sometimes even all functions called on a particular object attribute. Seeing the call arguments would be useful, too.

I can imagine writing decorators for all that, but then I'd still have to modify the source code in different places. And writing a class decorator which modifies all methods isn't that straightforward.

Is there a solution where I don't have to modify my source code? Ideally something which doesn't slow down Python too much.

Gere
  • 12,075
  • 18
  • 62
  • 94
  • 4
    Why not use Python's [built-in debugging tools](http://docs.python.org/2/library/debug.html)? – Steven Rumbalski Nov 27 '12 at 15:41
  • You could monkey patch `object` itself when in 'debug mode' and reconfigure `__getattribute__`, `__setattr__`, and maybe `__call__`, then use some sort of filtering mechanism to define which things you want to log and which not. Though @StevenRumbalski's question deserves answering first. – Silas Ray Nov 27 '12 at 15:41
  • Possible duplicate of http://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script, if you're interested in call counts, etc. – aquavitae Nov 27 '12 at 15:42
  • @Steven: I only know normal pdb usage. But I'd rather have a full program run and just a report of function calls. Is there a good solution with the debugging tools? – Gere Nov 27 '12 at 15:46
  • Profile: http://docs.python.org/2/library/profile.html – Austin Marshall Nov 27 '12 at 16:20

2 Answers2

1

Except decorators, for Python >= 3.0 you could use new __getattribute__ method for a class, which will be called every time you call any method of the object. You could look through Lutz "Learning Python" chapters 31, 37 about it.

moonsly
  • 612
  • 6
  • 11
  • `__getattribute__` exists in Python 2, too, as part of new-style classes introduced in Python 2.2. Not sure what you meant by "Except decorators"... – martineau Nov 27 '12 at 18:57
1

You ought to be able to implement something that does what you want using either sys.setprofile() or perhaps sys.settrace(). They both let you define a function to be called when specific "events" occur, like function calls, and pass additional information to which can be used to to determine the function/method being called and examine its arguments.

If you look around, there's probably sample usage code to use as a good starting point.

martineau
  • 119,623
  • 25
  • 170
  • 301