Reputation: 3707
For example, I have the following code:
def m1(num):
pass
def m2(num):
pass
def foo(num):
m2(num)
def foo2(num):
foo(num)
m1(num)
def main():
foo2(1)
if __name__ == "__main__":
main()
Is there a way to get call list for each function? For example, for this example I want to get the following dict:
main: foo2
foo2: foo, m1
foo: m2
m2:
m1:
I know only one way to complete my task. It is to use globals()
and then parse source code. But it seems is very ugly.
Upvotes: 0
Views: 162
Reputation: 365607
I know only one way to complete my task. It is to use
globals()
and then parse source code. But it seems is very ugly.
I'm not sure what you think parsing source code would do for you here.
If you want to build a dynamic call graph, what you want to do is decorate each function—replace it with a wrapper that does some extra stuff before or after calling the real function. For example:
def wrapper(func):
@functools.wraps
def wrap(*args, **kwargs):
# do stuff to update call graph
return func(*args, **kwargs)
return wrap
g = globals()
for name, value in g.items():
if callable(value):
g[name] = wrapper(value)
Or, maybe more simply (and more flexibly), you might want to use the bdb
debugger framework to step through your program and just record the user_call
instances.
If you want to build a static call graph, then obviously that comes from the source, but there's no reason to parse it yourself when Python comes with the ast
module to do it for you. (You can use inspect.getsource
to get the source code to parse.)
Upvotes: 1