Я написал библиотеку для такого рода вещей, которую я только что положил на GitHub на случай, если она кому-нибудь пригодится.
Она работает, оборачивая функции, классы илиобъекты с прокси, который регистрирует каждое взаимодействие. Это включает в себя не только имена методов, но также их аргументы и возвращаемые значения, и какие методы вызывали какие другие методы (в дереве).
Использование:
from tracer import tracer
@tracer
class classname(object):
def __init__(self):
self.hold = None
def funcname(self):
self.hold = 'a'
return self
def method(self, c):
self.hold = self.hold * c
return self
def recursive_method(self, n):
if n > 0:
self.recursive_method(n - 1)
self.recursive_method(n - 2)
c = classname().funcname().method(10)
c.recursive_method(3)
c.print_call_tree()
Вывод:
* +-> __init__()
|
+-> funcname() +-> <__main__.classname object at 0x0000000002A9EBA8>
|
+-> method(10) +-> <__main__.classname object at 0x0000000002AE2160>
|
+-> recursive_method(3) +-> recursive_method(2) +-> recursive_method(1) +-> recursive_method(0)
| | |
| | +-> recursive_method(-1)
| |
| +-> recursive_method(0)
|
+-> recursive_method(1) +-> recursive_method(0)
|
+-> recursive_method(-1)
Справедливое предупреждение: это немного хрупко, например, вы можете увидеть, что в журнале показаны разные идентификаторы для объекта, возвращаемого funcname
и method
, даже если это должен быть один и тот же объект стот же идентификатор.