• Python 动态创建函数【转】


    知乎上也有相似的问题

    偶然碰到一个问题,初想是通过动态创建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动态创建函数的几种方法/

  • 相关阅读:
    Improving the Safety, Scalability, and Efficiency of Network Function State Transfers
    MacOS下安装BeautifulSoup库及使用
    python爬虫调用搜索引擎及图片爬取实战
    2018软工项目UML设计(团队)
    【计算几何】如何计算两个圆的交点坐标
    【POJ 】POJ 3281. Dining
    【POJ 3233】矩阵多项式和
    【Effective C++】Effective C++笔记
    【图形学】图形学的23个基础问题
    【Google Code Jam】Millionaire
  • 原文地址:https://www.cnblogs.com/olivetree123/p/5067685.html
Copyright © 2020-2023  润新知