-2

我想将 exec 与一个非常简单的 python 代码一起使用,并列出调用的函数而不是调用它们。

如果我知道将调用哪些函数,我可以创建一个字典,将命名函数定义为print并将其用作exec.

我正在尝试使用自定义字典类,该类通过覆盖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上述结果。

4

2 回答 2

3

我可能是错的,但看起来你想要的是:

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

在这种情况下,而不是exec你想要ast模块

>>> 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']

函数的参数存储在对象的argsstarargskeywordskwargs属性中ast.Call

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

于 2013-05-09T19:16:17.627 回答
3

也许像下面这样?

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}
于 2013-05-09T19:24:02.253 回答