一尘不染

Python中可能有真正的动态和匿名函数?

python

正如可以使用type(name,base-classes,namespace-dict)创建动态类一样,可以创建动态函数吗?

我尝试按照以下方式做一些事情:

>>> f = type("f", (function,), {})
NameError: name 'function' is not defined

好吧,所以我会很聪明,但是:

>>> def fn():
...   pass
... 
>>> type(fn)
<type 'function'>
>>> f = type("f", (type(fn),), {})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: type 'function' is not an acceptable base type

Python是否以允许动态类的相同方式 专门 阻止动态函数的创建?

编辑:注意,我将禁止使用exec。由于我的问题是Python语言本身是否允许这样做。

提前致谢。


阅读 154

收藏
2020-12-20

共1个答案

一尘不染

还有types.FunctionType,你可以用它来动态地创建的功能,例如

def test_func(): print 'wow' 
dynf = types.FunctionType(test_func.func_code, {})
dynf()

输出:

wow

您可能会反对这不是动态的,因为我正在使用另一个函数的代码,但这仅是示例,这里有一种从python字符串生成代码的方法,例如

dynf = types.FunctionType(compile('print "really WoW"', 'dyn.py', 'exec'), {})
dynf()

输出:

really WoW

现在,这是动态的!

OP担心此类功能的动态性,因此这是另一个示例

dynf = types.FunctionType(compile('test_func():\ntest_func()', 'dyn.py', 'exec'), globals())
dynf()

输出:

wow
wow

注意:像这样创建Function对象似乎有局限性,例如,传递参数并不容易,因为要传递参数,我们需要将正确的co_argcount,co_varnames和其他12个变量传递给types.CodeType,理论上可以做到,但是容易出错,更简单的方法是将字符串作为模块导入,并且您具有完整的功能,例如

import types
import sys,imp

code = """def f(a,b,c):
    print a+b+c, "really WoW"
"""
module = imp.new_module('myfunctions')
exec code in module.__dict__
module.f('W', 'o', 'W')

输出:

WoW really WoW
2020-12-20