如何在python中使用exec来列出函数调用?

问题描述:

我想用一个非常简单的python代码使用exec并列出调用函数而不是调用它们。如何在python中使用exec来列出函数调用?

如果我知道哪些函数会被调用,我可以创建一个字典,将名称函数定义为print,并将其用作exec的第二个参数。

我试图使用由overwritting 的GetItem打印调用的函数的自定义词典类,但exec是没有帮助的发行:

TypeError: exec: arg 2 must be a dictionary or None 

有没有一种方法可以自定义函数调用中通用的方式?

编辑

举例来说,假设我有以下的配置文件,用Python编写的:

user('foo') 
password('foo123') 
home('/home/foo') 

user('bar') 
password('bar123') 
home('/home/foo') 

我需要运行这个文件,并打印其中包含的信息。我可以做到这一点下面的Python程序:

d = { 'user': print, 'password': print, 'home: 'print } 
execfile(filename, d, {}) 

这种方法的问题是,我有所有存在于文件中的函数初始化d。我试图使用自定义词典,它在getitem上做了一些不同的操作,并获得了上面的TypeError

+1

后一些代码,请 – 2013-05-09 19:10:40

+4

我读了3次,我仍然感到困惑。你想做什么? – CppLearner 2013-05-09 19:10:50

+2

这是一个解决方案的实际问题是什么? – 2013-05-09 19:12:55

也许像下面这样的东西?

class Printer(dict): 
    def __missing__(self, key): 
     def wrapped(*args, **kwargs): 
      print('{} called: args={}, kwargs={}'.format(key, args, kwargs)) 
     return wrapped 

code = ''' 
foo() 
bar(1, 2, baz=3) 
''' 

exec(code, Printer()) 

输出:

foo called: args=(), kwargs={} 
bar called: args=(1, 2), kwargs={'baz': 3} 
+2

这回答了OP的直接问题“是否有一种通用方法来定制函数调用?”很好。而且你甚至可以通过让'Printer .__ init__'捕获globals()'来扩展它,所以'__missing__'可以获取并调用真实函数(如果它是可调用的)。它仍然会错过称为函数的表达式,在'exec'块中定义的新函数等,但至少它会捕获间接调用的函数。 – abarnert 2013-05-09 20:53:49

+0

这正是我想要做的!谢谢! – Penz 2013-05-14 16:20:40

我可能是错的,但似乎你想要的是:

>>> the_functions_called_in('foo(); bar() + 4; lol(hello())') 
['foo', 'bar', 'lol', 'hello'] 

在这种情况下,而不是exec你想the ast module

>>> m = ast.parse('foo(); bar() + 4; lol(hello())') 
>>> [x.func.id for x in ast.walk(m) if isinstance(x, ast.Call)] 
['foo', 'lol', 'bar', 'hello'] 

该函数的参数存储在args,starargs,keywordskwargs对象的属性。

如果您想实际运行代码并跟踪哪些函数被调用(以及运行它们),请尝试profiling

+0

我需要参数... – Penz 2013-05-09 19:17:59

+0

@Penz这些存储在'Call'对象的属性中,正如我在编辑中提到的那样。 – Dougal 2013-05-09 19:22:29

+1

当然,如果你用'baz = foo; baz()'它会告诉你'baz'被调用而不是'foo',并且如果你用eval(“foo()”)来试试''它不会知道'foo'被调用, 等等。如果这是你想要做的事情,那就不可能正确编写。 Dougal的版本尽可能接近你可以获得的版本,并且它对于一些简单的探索性目的可能是有用的,但是尝试构建更强健的东西是一个非常非常糟糕的主意。 – abarnert 2013-05-09 19:32:40