我想用一个非常简单的python代码使用exec并列出调用的函数而不是调用它们。
如果我知道将调用哪些函数,我可以创建一个字典,将命名函数定义为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
。
答案 0 :(得分: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
和ast.Call
属性中。
如果您想实际运行代码并跟踪调用的函数(以及运行它们),请尝试profiling。
答案 1 :(得分: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}