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类定义的讲解
Nov 01 Python
python实现的用于搜索文件并进行内容替换的类实例
Jun 28 Python
浅谈tensorflow1.0 池化层(pooling)和全连接层(dense)
Apr 27 Python
matplotlib给子图添加图例的方法
Aug 03 Python
浅谈python下tiff图像的读取和保存方法
Dec 04 Python
Python寻找两个有序数组的中位数实例详解
Dec 05 Python
Python获取Redis所有Key以及内容的方法
Feb 19 Python
python 批量修改 labelImg 生成的xml文件的方法
Sep 09 Python
python GUI库图形界面开发之PyQt5动态加载QSS样式文件
Feb 25 Python
django 模型字段设置默认值代码
Jul 15 Python
python使用matplotlib绘制折线图的示例代码
Sep 22 Python
解决PDF 转图片时丢文字的一种可能方式
Mar 04 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 Mysql日期和时间函数集合
2007/11/16 PHP
php提示Warning:mysql_fetch_array() expects的解决方法
2014/12/16 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
2017/07/27 PHP
javascript之锁定表格栏位
2007/06/29 Javascript
javaScript(JS)替换节点实现思路介绍
2013/04/17 Javascript
JQuery弹出层示例可自定义
2014/05/19 Javascript
jQuery对象的selector属性用法实例
2014/12/27 Javascript
js改变embed标签src值的方法
2015/04/10 Javascript
javascript实现英文首字母大写
2015/04/23 Javascript
javascript常用的方法分享
2015/07/01 Javascript
angularjs创建弹出框实现拖动效果
2020/08/25 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
微信小程序的动画效果详解
2017/01/18 Javascript
原生js实现打字动画游戏
2017/02/04 Javascript
jQuery层级选择器实例代码
2017/02/06 Javascript
jquery实现弹窗功能(窗口居中显示)
2017/02/27 Javascript
微信小程序之GET请求的实例详解
2017/09/29 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
2018/10/08 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
2019/12/29 Javascript
vue实现全屏滚动效果(非fullpage.js)
2020/03/07 Javascript
Vue elementui字体图标显示问题解决方案
2020/08/18 Javascript
[08:02]DOTA2牵红线 zhou神抱得美人归
2014/03/22 DOTA
Python中的类与对象之描述符详解
2015/03/27 Python
python实现RSA加密(解密)算法
2016/02/17 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
pycharm修改界面主题颜色的方法
2019/01/17 Python
python添加模块搜索路径和包的导入方法
2019/01/19 Python
python 弧度与角度互转实例
2020/04/15 Python
python使用selenium爬虫知乎的方法示例
2020/10/28 Python
详解java调用python的几种用法(看这篇就够了)
2020/12/10 Python
Scholastic父母商店:儿童书籍
2017/01/01 全球购物
打造高效课堂实施方案
2014/03/22 职场文书
学习演讲稿范文
2014/05/10 职场文书
个人批评与自我批评材料
2014/10/17 职场文书
2016年校园社会综合治理宣传月活动总结
2016/03/16 职场文书
在校大学生才艺比赛策划书怎么写?
2019/08/26 职场文书