Python 如何在当前范围内动态执行函数并将其添加为调用函数的属性?

Python 如何在当前范围内动态执行函数并将其添加为调用函数的属性?,python,namespaces,code-generation,exec,abstract-syntax-tree,Python,Namespaces,Code Generation,Exec,Abstract Syntax Tree,我有一些这样的代码: def f1(): <some stuff here> . . . @mylib.codegen def f2(args): f1() <some more stuff here> def f1(): . . . @mylib.codegen def f2(参数): f1() mylib.py: def codegen(fn): src = inspect.getsource(fn) original_ast = ast.p

我有一些这样的代码:

def f1():
  <some stuff here>
.
.
.

@mylib.codegen
def f2(args):
  f1()
  <some more stuff here>
def f1():
.
.
.
@mylib.codegen
def f2(参数):
f1()
mylib.py:

def codegen(fn):
  src = inspect.getsource(fn)
  original_ast = ast.parse(src)
  new_ast = transform_ast(original_ast)
  code_obj = compile(new_ast, '<auto-generated>', 'exec')
  myscope = {}
  exec code_obj in myscope
  fn.generated_fn = myscope['name']   # Where name is the binding created by execing code_obj
def codegen(fn):
src=inspect.getsource(fn)
原始\u ast=ast.parse(src)
新建\u ast=转换\u ast(原始\u ast)
代码\u obj=compile(新的\u ast,,'exec')
myscope={}
myscope中的exec code_obj
fn.generated_fn=myscope['name']#其中name是通过执行代码_obj创建的绑定
总之,
mylib.codegen
是一个修饰符,它解析f的代码,基于
f
的ast创建另一个函数的ast,执行生成函数的代码以获得可调用函数,并将可调用函数设置为
f
的属性。这意味着当第一次导入
f2
时,
f2
动态地获取另一个函数作为其自身的属性

生成的函数也需要调用
f1
,但在
myscope
中找不到
f1
。如果Python允许内联,而我有
mylib.codegen
的内联代码,一切都会很好,但我认为Python不允许代码内联。
如何设置以使生成的代码对象在调用函数的名称空间中执行?

函数的全局名称空间包含给定函数的全局名称空间;您需要它才能执行转换和重新编译的代码对象:

myscope = {}
myscope.update(fn.func_globals)

不要直接使用
fn.func_globals
;您不希望覆盖该命名空间中的项

函数全局范围可以在
fn.func_globals
中找到;也许可以用它更新myscope。@MartijnPieters-谢谢,
fn.func\u globals
起作用了。我只是需要做点什么。为了给您一个高层次的想法,我们为每个函数编写一个函数来处理函数所需的所有数据。手动编写和维护所有这些代码是重复的,我正在尝试将其自动化。