• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Python骚操作动态定义函数

python 搞java代码 3年前 (2022-06-26) 40次浏览 已收录 0个评论

在 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”)。

  1. name(可选)
    管制所返回的函数的__name__ 属性。只真正对 lambdas 有用(因为匿名性,它们通常没有名称),并且重命名函数。
  2. argdefs(可选)
    通过传入一个蕴含任意类型的对象的元组,提供一个形式来供给默认参数值(def
foo(bar="baz"))。(FunctionType((lambda bar: bar).__code__, {}, "foo", (10,))() == 10)。
  1. 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 编程学习圈 ,发送 “J” 即可收费获取,每日干货分享


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Python骚操作动态定义函数

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址