如何在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
。
也许像下面这样的东西?
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}
我可能是错的,但似乎你想要的是:
>>> 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
,keywords
和kwargs
对象的属性。
如果您想实际运行代码并跟踪哪些函数被调用(以及运行它们),请尝试profiling。
我需要参数... – Penz 2013-05-09 19:17:59
@Penz这些存储在'Call'对象的属性中,正如我在编辑中提到的那样。 – Dougal 2013-05-09 19:22:29
当然,如果你用'baz = foo; baz()'它会告诉你'baz'被调用而不是'foo',并且如果你用eval(“foo()”)来试试''它不会知道'foo'被调用, 等等。如果这是你想要做的事情,那就不可能正确编写。 Dougal的版本尽可能接近你可以获得的版本,并且它对于一些简单的探索性目的可能是有用的,但是尝试构建更强健的东西是一个非常非常糟糕的主意。 – abarnert 2013-05-09 19:32:40
后一些代码,请 – 2013-05-09 19:10:40
我读了3次,我仍然感到困惑。你想做什么? – CppLearner 2013-05-09 19:10:50
这是一个解决方案的实际问题是什么? – 2013-05-09 19:12:55