Python 中可能实现真正的动态和匿名函数吗? [英] True dynamic and anonymous functions possible in Python?

查看:37
本文介绍了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屋!

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