经过测试和确认使用Python3.5和Python3.6
基本想法归功于PatrickHaugh¹
实现(解析dis输出)是我自己的:
建立:import dis
# setup test environment
def a(_,__):
pass
def b(_,__,___):
pass
def c(_):
pass
def g():
pass
d = 4
def test(flag):
e = c
if flag:
a(a(b,c), [l for l in g()])
else:
b(a, flag, c(e))
d = d + 1
def calculate(a, b, operator):
if operator == Operator.add:
add(a, b)
elif operator == Operator.subtract:
subtract(a, b)
class Operator(object):
add = "add"
subtract = "subtract"
码:def get_function_calls(func):
# the used instructions
ins = [i for i in dis.get_instructions(func)][::-1]
# dict for function names (so they are unique)
names = {}
# current line
i = len(ins) - 1
# while there are still CALL_FUNCTIONs left
while len(ins) > 0:
# find last CALL_FUNCTION
while i>-1 and ins[i].opname != "CALL_FUNCTION":
i -= 1
# abort if done
if i == -1:
break
# function takes this number of arguments
n_params = ins[i].arg
# LOAD that loaded this function
entry = ins[i+n_params+1]
# ignore list comprehensions / ...
if "." not in entry.argval:
# save name of this function
names[ins[i+n_params+1].argval] = True
# reduce this CALL_FUNCTION and all its paramters to one entry
ins = ins[:i] + [ins[i+n_params+1]] +ins[i+n_params+2:]
return sorted(list(names.keys()))
输出:> print(get_function_calls(test))
> ['a', 'b', 'c', 'g']
> print(get_function_calls(calculate))
> ['add', 'subtract']
¹As 帕特里克霍先生的有关评论dis是在2h老我认为这是一个免费服用...