我有一个想法,可以通过类似下面的装饰器来转换所有给定的使用装饰器标记的函数:
@transform_ast
def foo(x):
return x
在 transform_ast
中,我获取源代码,提取抽象语法树(AST),对其进行变换,然后再次从中创建代码对象和函数类型。大致如下所示:
import ast
import inspect
import types
class Rewrite(ast.NodeTransformer):
pass
def transform_ast(f):
source = inspect.getsource(f)
source = '\n'.join(source.splitlines()[1:]) # remove the decorator first line.
print(source)
old_code_obj = f.__code__
old_ast = ast.parse(source)
new_ast = Rewrite().visit(old_ast)
new_code_obj = compile(new_ast, old_code_obj.co_filename, 'exec')
new_f = types.FunctionType(new_code_obj, {})
return new_f
@transform_ast
def foo(x):
return x
然而,当我随后调用foo(x)时,它似乎不能正常工作。
实际上,我们可以假设我的转换只是将return x
重写为return x+1
。理想情况下,我希望一切都像往常一样正常工作,包括能够使用调试器进入函数...
调用foo(10)
会出现以下错误:
TypeError: module() takes no arguments (1 given)
我做错了什么吗?
def foo(): return range(10)
一起使用。 - BPL@transform_ast
。 - BPL