Python 中可能实现真正的动态和匿名函数吗? [英] True dynamic and anonymous functions possible in Python?
问题描述
就像可以使用 type(name, base-classes, namespace-dict) 创建动态类一样,是否可以创建动态函数?
我试过做一些类似的事情:
<预><代码>>>>f = type("f", (function,), {})NameError:未定义名称函数"好的,所以我会很聪明,但是:
<预><代码>>>>定义 fn():... 经过...>>>类型(fn)<输入'函数'>>>>f = type("f", (type(fn),), {})回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中类型错误:类型函数"不是可接受的基类型Python 是否特别像允许动态类一样阻止动态函数的创建?
注意,我不允许使用 exec.. 因为我的问题是 Python 语言本身是否允许这样做.
提前致谢.
types.FunctionType
可用于动态创建函数,例如
def test_func(): 打印 'wow'dynf = types.FunctionType(test_func.func_code, {})动态()
输出:
哇
你可能反对这不是动态的,因为我使用的是另一个函数的代码,但这只是一个例子,有一种方法可以从 python 字符串生成代码,例如
dynf = types.FunctionType(compile('print "really WoW"', 'dyn.py', 'exec'), {})动态()
输出:
真的哇
现在是动态的!
OP 担心此类函数的动态特性,所以这里是另一个例子
dynf = types.FunctionType(compile('test_func():\ntest_func()', 'dyn.py', 'exec'), globals())动态()
输出:
哇哇
注意:像这样创建 Function 对象似乎有限制,例如传递参数并不容易,因为传递参数需要将正确的co_argcount、co_varnames等12个变量传递给types.CodeType
,理论上可以做到,但是容易出错,比较简单的方法是将字符串作为模块导入,并且您拥有完整的功能,例如
导入类型导入系统,imp代码 = """def f(a,b,c):打印 a+b+c,真的哇""""module = imp.new_module('myfunctions')执行 module.__dict__ 中的代码module.f('W', 'o', 'W')
输出:
哇真的哇
Just as a dynamic class can be created using type(name, base-classes, namespace-dict), can a dynamic function be created?
I've tried doing something along the lines of:
>>> f = type("f", (function,), {})
NameError: name 'function' is not defined
Ok, so I'll be clever, but:
>>> 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
Does Python specifically prevent the creation of dynamic functions in the same way it allows dynamic classes?
Edit: Note, I'd disallow any use of exec.. Since my question is does the Python language itself permit this.
Thanks in advance.
There is types.FunctionType
which you can use to dynamically create a function e.g.
def test_func(): print 'wow'
dynf = types.FunctionType(test_func.func_code, {})
dynf()
Output:
wow
You might object that this is not dynamic because I am using code from another function, but that was just an example there is a way to generate code from python strings e.g.
dynf = types.FunctionType(compile('print "really WoW"', 'dyn.py', 'exec'), {})
dynf()
Output:
really WoW
Now that is dynamic!
OP is worried about the dynamic nature of such function so here is another example
dynf = types.FunctionType(compile('test_func():\ntest_func()', 'dyn.py', 'exec'), globals())
dynf()
Output:
wow
wow
Note:
Creating Function object like this seems to have limitations e.g. it is not easy to pass arguments, because to pass arguments we need to pass correct co_argcount, co_varnames and other 12 variables to types.CodeType
, which theoretically can be done but will be error prone, an easier way is to import string as a module and you have a full fledged function e.g.
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')
Output:
WoW really WoW
这篇关于Python 中可能实现真正的动态和匿名函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!