如何在当前范围内动态执行函数并将其添加为调用函数的属性? [英] How can I dynamically execute function in current scope and add it as property of the calling function?

查看:52
本文介绍了如何在当前范围内动态执行函数并将其添加为调用函数的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些类似这样的代码:

I have some code like this:

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

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

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

总而言之,mylib.codegen是一个装饰器,它解析f的代码,基于f的ast创建另一个函数的ast,执行生成函数的代码以获取可调用函数并将可调用函数设置为f的属性. f.这意味着当第一次导入f2时,f2动态获取另一个函数作为其自身的属性.

To summarize, mylib.codegen is a decorator which parses code of f, creates an ast of another function based on ast of f, execs code of generated function to get a callable function and sets callable function as a property of f. That means when f2 is imported the first time, f2 dynamically gets another function as property of itself.

生成的函数还需要调用f1,但是在myscope中找不到f1.如果Python以某种方式允许内联,并且我已经内联了mylib.codegen的代码,一切都会好起来的,但是我认为Python不允许内联代码. 我该如何设置以便在调用者函数的命名空间中执行生成的代码对象?

Generated function also needs to call f1 but it can't find f1 in myscope. If somehow Python allowed inlining, and I had inlined code of mylib.codegen, everything would have been fine but I don't think Python allows inlining of code. How do I set things up so that generated code object is execed in namespace of caller function?

推荐答案

fn.func_globals包含给定函数的全局名称空间;您将需要它来执行转换并重新编译的代码对象:

The fn.func_globals contains the global namespace for a given function; you'll need it to be able to exec the transformed and recompiled code object:

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

请勿直接使用fn.func_globals;您不想覆盖该命名空间中的项目.

Do not use fn.func_globals directly; you wouldn't want to overwrite items in that namespace.

这篇关于如何在当前范围内动态执行函数并将其添加为调用函数的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆