知乎上也有相似的问题

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

Python 动态创建函数【转】的更多相关文章

  1. python 动态创建变量 获取变量名

    参考链接:https://www.cnblogs.com/technologylife/p/9211324.html 参考链接(未)(使用inspect 获取变量名):https://blog.csd ...

  2. python动态创建类的声明

    动态创建类的声明 使用内置函数type,原型:class type(name, bases, dict)name是类的名字,相当于__class__bases是类的基类,元组,可以有多个基类,但是基类 ...

  3. Python(2):创建函数模块

    说明: 在使用python的时候我们除了使用内置的函数之外,可能还需要使用一些别人写的函数.或者我们写的代码也希望可以给其他人使用.要实现这样的功能,我们就需要按照下面的步骤来定义自己的模块: Ste ...

  4. python动态调用函数

    callmap = {ts.get_stock_basics: 'D:/dxw/code/all.csv', ts.get_sz50s: 'D:/dxw/code/50.csv', ts.get_hs ...

  5. MFC原理第四讲.动态创建机制

    MFC原理第四讲.动态创建机制 一丶要学习的知识点以及简介 动态创建是什么意思? 动态创建其实就是跟C++的new一样.都是创建对象.但是规避了C++语法的缺陷. 例如: char * ClassNa ...

  6. MFC六大核心机制之三:动态创建

    MFC中很多地方都使用了动态创建技术.动态创建就是在程序运行时创建指定类的对象.例如MFC的单文档程序中,文档模板类的对象就动态创建了框架窗口对象.文档对象和视图对象.动态创建技术对于希望了解MFC底 ...

  7. Python中使用type、metaclass动态创建方法和属性

    1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ...

  8. [Python]利用type()动态创建类

    Python作为动态语言,可以动态地创建函数和类定义.比如说定义一个Hello类,就写一个hello.py模块: #! /usr/bin/env python #coding=utf-8 class ...

  9. Python: 为对象动态添加函数,且函数定义来自一个str

    转自:http://blog.sina.com.cn/s/blog_55a11f330100ab1x.html 在Python中,通常情况下,你只能为对象添加一个已经写好的方法 需求:传入一个str类 ...

随机推荐

  1. Linux 进程与线程五

    pthread_self函数 pthread_t pthread_self(void); 一般会成功,返回当前线程的ID 注意:在子线程中执行exit()函数会退出整个进程,一般使用pthread_e ...

  2. [LeetCode] Wiggle Sort 摆动排序

    Given an unsorted array nums, reorder it in-place such that nums[0] <= nums[1] >= nums[2] < ...

  3. 2016BUAA校赛决赛

    A. 题意:有n个点,n-1条边,1-2-3-4-5-...-n,每条边都有权值,代表走这条边的时间,时刻0一个人在点1,问从时刻1~m,有哪些时刻这个人可能走到n点 分析:将每条边当作物品,可以选1 ...

  4. Todo list and 学习心得

    1. 理论实践要区分起来学习,结合起来运用. 2. 内事不决问百度外事不决问谷歌 3. 一个人走的快,一群人走得远或者更快 2016-09-01 23:27:58  九月目标:对程序从编译到执行的整个 ...

  5. RabbitMQ总结概念

    AMQP:一个提供统一消息服务的应用层标准高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计 http://www.diggerplus.org/archives/3110 AMQP ...

  6. pip安装使用详解(转)

    pip类似RedHat里面的yum,安装Python包非常方便.本节详细介绍pip的安装.以及使用方法. 1.pip下载安装 1.1 pip下载   1 # wget "https://py ...

  7. react-redux原理分析

    写在前面 之前写了一篇分析Redux中Store实现的文章(详见:Redux原理(一):Store实现分析),突然意识到,其实React与Redux并没有什么直接的联系.Redux作为一个通用模块,主 ...

  8. Python后台分页删除编辑查询

    「POST 数据」通常指 POST 时 body 中的数据.而 QueryString (URL)中也有可以带参数(通常是 GET 时的参数).如果 POST 时同时存在 QueryString 和 ...

  9. 一.Jmeter+Ant+Jenkins搭建持续集成接口性能自动化测试

    微创新作品信息 1)微创新作品描述 A.为什么诞生: 1. 接口测试是测试系统组件间接口的一种测试.接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点.测试的重点是要检查数据的交换, ...

  10. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...