我正在研究一些代码(不是我的代码),我试图将其设置为。
继承树中有16个类。
根据inspect.getmro(self.__class__)
我想跟踪一下如果我拨打self.do_magic()
会发生什么。
我希望看到这16个类的所有do_magic()
次调用。
理想的解决方案如下:
result_of_do_magic, list_of_do_magic_methods = trace_method_calls(self.do_magic)
我不知道如何实施trace_method_calls()
。它应该执行代码并在运行时跟踪方法调用。
是否有一位追踪专家知道如何做到这一点?
AFAIK这需要在运行时完成,因为我不知道所有方法是否都通过do_magic()
调用父母的super()
。
我不想修改代码以便能够跟踪它。我想这应该是可能的,因为模拟库可以做类似的魔术。
答案 0 :(得分:4)
如果我理解正确,我可以在这里看到2个解决方案。
1)[Brute-ish且相对简单]查找所有出现的" do_magic"在你的代码中,用装饰器包装它,如:
def trace_this(fn):
def wrapped(*args, **kwargs):
print("do_magic is called!")
result = fn(*args, **kwargs)
print("Result is:{0}".format(result))
return result
return wrapped
...
@trace_this
def do_magic():
...
2)运行django as:
python -m trace -t manage.py runserver 127.0.0.1:8000 --noreload > trace.txt
并且所有调用的代码都在trace.txt中,然后您可以使用自己喜欢的工具进行解析/分析。
答案 1 :(得分:0)
根据我的理解,您想要的是特定函数的外部框架调用,以查看调用哪些类来导致相关方法。
下面是一个POC来演示它是如何工作的。你可以用它来构建一个装饰器。
from __future__ import print_function
import inspect
class A:
def a(self):
stacks = inspect.getouterframes(inspect.currentframe())
for stack in stacks:
frame = stack[0]
klass = frame.f_locals.get("self")
mthd = frame.f_code.co_name
if klass: # to avoid printing modules
print('Called by class: {0}, method: {1}'.format(klass.__class__.__name__, mthd))
class B:
def b(self):
bb = A()
bb.a()
class C:
def c(self):
cc = B()
cc.b()
z = C()
z.c()
Class C
拨打Class B
,然后拨打Class A
A.a()
时,所有继承A
的类都在外框中。A.a()
的功能来创建装饰器,以便打印通向函数调用的所有外框。