这个周末,我一直在拆分Michele Simionato的decorator module,它构建了保留签名的装饰器。它的核心是一个动态生成的函数,它的工作原理类似于......
src = """def function(a,b,c) :\n return _caller_(a,b,c)\n"""
evaldict = {'_caller_' : _caller_}
code = compile(src, '<string>', 'single')
exec code in evaldict
new_func = evaldict[function]
我发现,使用这段代码搞错了,编译步骤可以完全避免,只需一个:
exec src in evaldict
现在,我确信这个额外步骤有充分的理由,但我无法找到两种方法之间的区别。性能
既然我问,是否有类似的东西,即定义一个新函数并获得它的句柄,用eval实现?我试过了,但无法让它工作......
答案 0 :(得分:2)
我看到了一些差异。首先,compile
在语法错误方面的语义略好于exec
。我怀疑真正的原因是compile
的定义在处理exec
稍微不那么精确的新行字符方面非常明确。
我很好奇为什么compile
和exec
被用来代替内部功能。我不知道compile
/ exec
可以让你控制全局变量。非常有趣。
答案 1 :(得分:2)
compile()允许您控制创建的代码对象及其名称和来源,而exec则不那么灵活。也值得这样做,以便其他人在阅读你的代码时,会学到它们是单独的步骤并在以后考虑到这一点,当他们需要多次执行相同的代码时(其中compile()一次,exec多次会是更快,并编写代码来教育下一个阅读它的人,这对设计选择总是有价值的影响。