如何调用已编译的函数体? [英] How to call a compiled function body?

查看:36
本文介绍了如何调用已编译的函数体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我获得一个代码对象(通过 Python 3 中的 .func_code__code__ 之类的内部结构)时,有没有办法调用 这段代码?简单地调用它是行不通的:

When I get hold of a code object (via internals like .func_code or __code__ in Python 3), is there any way of calling this piece of code? Simply calling it does not work:

def f(): pass

f.func_code()

结果

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'code' object is not callable

当您想对嵌套函数进行单元测试时,这会派上用场:

This can come in handy when you like to unit-test a nested function:

def f():
  def g():
    return 3
  f.x = g
  return g() + 1

f.func_code.co_consts[1]

结果

<code object g at 0x7f123991b930, file "<stdin>", line 2>

当然,这段代码仍然需要上下文等,但这不是我的问题.

Of course, this piece of code still needs a context etc. but that's not my question here.

推荐答案

可以eval()exec 它们.

如果它们有自由变量(例如对于嵌套函数的代码,其外部函数在嵌套函数之前定义了局部变量),这是不可能直接实现的(evalexec 在这种情况下引发 TypeError).

If they have free variables (e. g. for the code of nested functions whose outer function has local variables defined before the nested function), this is not directly possible (eval or exec raise a TypeError in this case).

此外,不能直接将参数传递给代码.

Also, passing arguments to the code is not directly possible.

但是可以即时为给定的代码创建一个包装函数.这个函数通常可以被调用(使用 f(…)),以通常的方式传递参数.这是使用 types.FunctionType 完成的.为了实现对自由变量的引用,必须使用一种技巧来获得Python所期望的正确数据类型.请参阅下面的代码以获取示例:

But one can create a wrapping function for the given code on-the-fly. This function can normally be called (using f(…)), passing arguments in the usual way. This is done using types.FunctionType. To achieve references to free variables, one must use a trick in order to get the correct data type as Python expects it. See the code below for an example:

def f(v1=1):
  v2 = 2
  def g(v3=4):
    return v1 + v2 + v3 + 8
  return g() + 16

def freeVar(val):
  def nested():
    return val
  return nested.__closure__[0]

def nested(outer, innerName, **freeVars):
  if isinstance(outer, (types.FunctionType, types.MethodType)):
    outer = outer.func_code
  for const in outer.co_consts:
    if isinstance(const, types.CodeType) and const.co_name == innerName:
      return types.FunctionType(const, globals(), None, None, tuple(
          freeVar(freeVars[name]) for name in const.co_freevars))

nestedG = nested(f, 'g', v1=1, v2=2)
print nestedG(4)  # will print 15

这篇关于如何调用已编译的函数体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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