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采集腾讯新闻实例
Jul 10 Python
Python常用随机数与随机字符串方法实例
Apr 09 Python
MySQL最常见的操作语句小结
May 07 Python
详细解读Python中解析XML数据的方法
Oct 15 Python
Python文本相似性计算之编辑距离详解
Nov 28 Python
利用python模拟实现POST请求提交图片的方法
Jul 25 Python
Python正则捕获操作示例
Aug 19 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
Dec 18 Python
Python实现的朴素贝叶斯分类器示例
Jan 06 Python
python模仿网页版微信发送消息功能
Feb 24 Python
windows下python安装小白入门教程
Sep 18 Python
Python的代理类实现,控制访问和修改属性的权限你都了解吗
Mar 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版(3)
2006/10/09 PHP
一个基于PDO的数据库操作类(新) 一个PDO事务实例
2011/07/03 PHP
PHP中获取内网用户MAC地址(WINDOWS/linux)的实现代码
2011/08/11 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
PHP实现网页内容html标签补全和过滤的方法小结【2种方法】
2017/04/27 PHP
[推荐]javascript 面向对象技术基础教程
2009/03/03 Javascript
js中if语句的几种优化代码写法
2011/03/12 Javascript
Jquery chosen动态设置值实例介绍
2013/08/08 Javascript
jQuery获取父元素节点、子元素节点及兄弟元素节点的方法
2016/04/14 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
2016/05/28 Javascript
BootStrap日期控件在模态框中选择时间下拉菜单无效的原因及解决办法(火狐下不能点击)
2016/08/18 Javascript
JS比较两个数值的大小实例
2016/11/25 Javascript
基于jQuery实现的查看全文功能【实用】
2016/12/11 Javascript
js生成随机数方法和实例
2017/01/17 Javascript
react性能优化达到最大化的方法 immutable.js使用的必要性
2017/03/09 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
vue动态删除从数据库倒入列表的某一条方法
2018/09/29 Javascript
jquery+css实现Tab栏切换的代码实例
2019/05/14 jQuery
js实现限定范围拖拽的示例
2020/10/26 Javascript
Python实现的检测网站挂马程序
2014/11/30 Python
Python多线程编程(七):使用Condition实现复杂同步
2015/04/05 Python
python虚拟环境virtualenv的安装与使用
2017/09/21 Python
centos6.8安装python3.7无法import _ssl的解决方法
2018/09/17 Python
全面了解django的缓存机制及使用方法
2019/07/22 Python
python图的深度优先和广度优先算法实例分析
2019/10/26 Python
python入门之基础语法学习笔记
2020/02/08 Python
windows10环境下用anaconda和VScode配置的图文教程
2020/03/30 Python
美国婴童服装市场上的领先品牌:Carter’s
2018/02/08 全球购物
Ariat官网:美国马靴和服装品牌
2019/12/16 全球购物
泰国在线书店:SE-ED
2020/06/21 全球购物
如何做好总经理助理
2013/11/12 职场文书
网上开商店的创业计划书
2014/01/19 职场文书
毕业生自荐书
2014/02/02 职场文书
教师求职自荐信
2014/03/09 职场文书
小时代观后感
2015/06/10 职场文书
国庆节主题班会
2015/08/15 职场文书