Python骚操作之动态定义函数


Posted in Python onMarch 26, 2019

在 Python 中,没有可以在运行时简化函数定义的语法糖。然而,这并不意味着它就不可能,或者是难以实现。

from types import FunctionType

foo_code = compile('def foo(): return "bar"', "<string>", "exec")
foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")

print(foo_func())

输出:bar

剖析

逐行检视代码,你会发现语言/解释器的屏障是多么脆弱。

>>> from types import FunctionType

Python 文档通常不会列出那些非用于手动创建的类的特征(这是完全合理的)。有三种方法可以解决这个问题:help()、inspect(无法查看内置方法)、以及最后的解决方案,即查看 CPython 源代码。

在本例中,help() 与 inspect 都可以完成工作,但是查看实际的源代码,则会揭示出关于数据类型的更多细节。

>>> from inspect import signature
>>> signature(FunctionType)
<Signature (code, globals, name=None, argdefs=None, closure=None)>

1. code

内部是一个PyCodeobject,作为types.CodeType对外开放。非内置方法拥有一个__code__属性,该属性保存了相应的代码对象。利用内置 compile() 方法,可以在运行期创建types.CodeType对象。

2. globals

如果一个函数引用的变量不是在局部定义的,而是作为参数转入、由默认参数值提供、或者通过闭包上下文提供,则它会在 globals 字典中查找。

内置的 globals() 方法会返回一个对当前模块的全局符号表(global symbol table)的引用 ,因此能被用来提供一个总是与当前表的状态相一致的字典。传入任意其它的字典也是可以的(FunctionType((lambda: bar).__code__, {"bar" : "baz"}, "foo")() == "baz")。

3. name(可选)

控制所返回的函数的__name__ 属性。只真正对 lambdas 有用(由于匿名性,它们通常没有名称),并且重命名函数。

4. argdefs(可选)

通过传入一个包含任意类型的对象的元组,提供一个方式来供应默认参数值(def foo(bar="baz"))。(FunctionType((lambda bar: bar).__code__, {}, "foo", (10,))() == 10)。

5. closure(可选)

(如果需要在 CPython(PyPy,Jython,…)以外的其它 Python VM 中执行,可能不应该触及,因为它严重地依赖于实现细节)。

一个cell 对象的元组。创建 cell 对象并非完全是直截了当的,因为需要调用 CPython 的内部组件,但有一个库可以令它更加方便:exalt(无耻的广告)。(译注:这个库是作者开发的。)

>>> foo_code = compile('def foo(): return "bar"', "<string>", "exec")

compile() 是一个内置方法,因此同时也是文档丰富的。

exec 模式被用到,因为定义函数需用多个语句。

>>> foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")

聚合全部内容,并将动态创建的函数指定给一个变量。

那个被前一句代码编译成的函数,成为了生成的代码对象的第一个常量,因此仅仅指向 foo_code 是不充分的。这是 exec 模式的直接后果,因为生成的代码对象可以包含多个常量。

>>> print(foo_func())

动态生成的函数可以像其它函数一样被调用。

结尾

除了做实验,需要用到动态创建函数的场景很少。

玩耍(Toying around) Python 的内部构件是一种深入学习这门语言的好方法。

如果需要,可以毫不费力地越过解释器/语言的界线。

还是一如既往地:不要滥用语言 (好吧,一点点也无妨,对吧?)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
对于Python中RawString的理解介绍
Jul 07 Python
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
Jul 11 Python
Python数据操作方法封装类实例
Jun 23 Python
python实现简单中文词频统计示例
Nov 08 Python
Python学习pygal绘制线图代码分享
Dec 09 Python
PyQt5 pyqt多线程操作入门
May 05 Python
Python中常用的内置方法
Jan 28 Python
python基于json文件实现的gearman任务自动重启代码实例
Aug 13 Python
python调用函数、类和文件操作简单实例总结
Nov 29 Python
python不到50行代码完成了多张excel合并的实现示例
May 28 Python
使用python画出逻辑斯蒂映射(logistic map)中的分叉图案例
Dec 11 Python
python asyncio 协程库的使用
Jan 21 Python
python 将有序数组转换为二叉树的方法
Mar 26 #Python
浅谈Python爬虫基本套路
Mar 25 #Python
我用Python抓取了7000 多本电子书案例详解
Mar 25 #Python
详解python:time模块用法
Mar 25 #Python
Python minidom模块用法示例【DOM写入和解析XML】
Mar 25 #Python
Python实例方法、类方法、静态方法的区别与作用详解
Mar 25 #Python
详解Python装饰器
Mar 25 #Python
You might like
解析php中如何直接执行SHELL
2013/06/28 PHP
PHP Curl模拟登录微信公众平台、新浪微博实例代码
2016/01/28 PHP
php7函数,声明,返回值等新特性介绍
2018/05/25 PHP
laravel csrf排除路由,禁止,关闭指定路由的例子
2019/10/21 PHP
JQuery插件Quicksand实现超炫的动画洗牌效果
2015/05/03 Javascript
Jquery easyui 实现动态树
2015/11/17 Javascript
js立即执行函数: (function ( ){})( ) 与 (function ( ){}( )) 有什么区别?
2015/11/18 Javascript
详解JavaScript for循环中发送AJAX请求问题
2020/06/23 Javascript
angular route中使用resolve在uglify压缩后问题解决
2016/09/21 Javascript
nodejs基础应用
2017/02/03 NodeJs
JS中使用正则表达式g模式和非g模式的区别
2017/04/01 Javascript
微信小程序 获取session_key和openid的实例
2017/08/17 Javascript
小程序实现发表评论功能
2018/07/06 Javascript
详解Vue CLI3配置之filenameHashing使用和源码设计使用和源码设计
2018/08/31 Javascript
解决前后端分离 vue+springboot 跨域 session+cookie失效问题
2019/05/13 Javascript
Vue 数组和对象更新,但是页面没有刷新的解决方式
2019/11/09 Javascript
create-react-app中添加less支持的实现
2019/11/15 Javascript
VueCli4项目配置反向代理proxy的方法步骤
2020/05/17 Javascript
[34:10]Secret vs VG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.24
2019/09/10 DOTA
高性能web服务器框架Tornado简单实现restful接口及开发实例
2014/07/16 Python
使用python绘制常用的图表
2016/08/27 Python
Python图形绘制操作之正弦曲线实现方法分析
2017/12/25 Python
Python Selenium 之数据驱动测试的实现
2019/08/01 Python
Python如何实现在字符串里嵌入双引号或者单引号
2020/03/02 Python
HTML5 创建canvas元素示例代码
2014/06/04 HTML / CSS
12个不为大家熟知的HTML5设计小技巧
2016/06/02 HTML / CSS
外贸业务员求职自荐信分享
2013/09/21 职场文书
医院实习接收函
2014/01/12 职场文书
出国留学介绍信
2014/01/13 职场文书
银行先进个人事迹材料
2014/05/11 职场文书
机关作风建设工作总结
2014/10/23 职场文书
党员民主生活会材料
2014/12/15 职场文书
综合素质自我评价评语
2015/03/06 职场文书
大学生敬老院活动总结
2015/05/07 职场文书
电话营销开场白
2015/05/29 职场文书
采购员工作总结范文
2015/08/12 职场文书