偶然碰到一个问题,初想是通过动态创建Python函数的方式来解决,于是调研了动态创建Python函数的方法。
定义lambda函数
在Python中定义lambda函数的写法很简单,
func = lambda: "foobar"
可以认为lambda函数是最常用的一种方式。
定义局部函数
Python中函数可以在代码块中进行定义,比如decorator就是通过这种方式实现的,
def decorator(func): def _(*args, **kwargs): return func(*args, **kwargs) return _
通过types.FunctionType创建函数
Python标准库中的types.FunctionType也可以用于创建函数,常见有如下两种使用方式,
- 从已有函数构建心函数
def foobar(): return "foobar" dynamic = types.FunctionType(foobar.__code__, {})
- 配合compile函数构建
module_code = compile(‘def foobar(): return "foobar"‘, ‘‘, ‘exec‘) function_code = [c for c in module_code.co_consts if isinstance(c, types.CodeType)][0] foobar = types.FunctionType(function_code, {}) print foobar()
通过ast创建函数
除了通过compile()直接编译字符串代码之外,Python中也可以直接创建ast相关对象,最终再通过compile(), types.FunctionType进行构建,
from ast import * import types function_ast = FunctionDef( name=‘foobar‘, args=arguments(args=[], vararg=None, kwarg=None, defaults=[]), body=[Return(value=Num(n=42, lineno=1, col_offset=0), lineno=1, col_offset=0)], decorator_list=[], lineno=1, col_offset=0 ) module_ast = Module(body=[function_ast]) module_code = compile(module_ast, "<>", "exec") function_code = [c for c in module_code.co_consts if isinstance(c, types.CodeType)][0] foobar = types.FunctionType(function_code, {}) print foobar()
通过eval创建函数
最后还有一个eval函数,
foobar = eval(‘lambda: "foobar"‘)
在eval函数中不能直接通过def定义函数,所以尝试定义lambda函数进行替代。
其它方法
除了上面罗列的还有些旁的方法,比如,
将函数定义写入到单独的py文件中,而后通过 __import__ 操作导入模块来获取定义的函数。
总结
绝大部分应用场景下通过lambda或decorator就足以应付需求了,不过动态语言的函数就是真的想动态的搞,也是能找到方法的。
原文:http://soliloquize.org/2015/07/02/Python动态创建函数的几种方法/
时间: 2024-10-06 22:43:21