python笔记76-types.FunctionType 动态创建函数
创始人
2024-03-03 20:08:29

前言

types.FunctionType 创建函数有2种方式:

  1. 从已有函数的基础上,创建一个新函数
  2. 从一个compile 构建的函数对象上,创建一个新函数

FunctionType 使用

FunctionType 可以用于判断一个对象是不是函数

from types import FunctionType, MethodTypedef func():print("hello")class Demo:x = 1def fun(self):print(self.x)@staticmethoddef fun2():print("f2")print(type(func))  # 
x = Demo()
print(type(x.fun))  # 
print(type(x.fun2))  # # 判断是函数还是方法
print(isinstance(func, FunctionType))  # True
print(isinstance(x.fun, MethodType))  # True
print(isinstance(x.fun2, FunctionType))  # True

创建新函数

从已有函数的基础上,创建一个新函数
5个参数

  • code是函数体的code对象
  • globals就是当前环境下的globals变量
  • name就是函数本身的名字
  • argdefs保存了函数的默认参数,这里可以注意到,code里只包含函数执行的逻辑,而默认参数则是在函数声明里
  • closure是闭包的变量,换句话说是既不在locals里,也不在globals的变量
import typesdef foobar():return "foobar"dynamic_fun = types.FunctionType(foobar.__code__, {})
print(dynamic_fun())  # foobar

配合compile函数 创建函数

使用示例

import typesf = """
def foobar(): return "foobar"
"""# 字符串编译成code
module_code = compile(f, '', 'exec')
# 从编译的code obj 取出CodeType 类型
function_code = module_code.co_consts[0]
foobar = types.FunctionType(function_code, {})
print(foobar())

FunctionType 需传一个CodeType 类型,可以从compile() 函数编译后的code取出编译后的code 类型

动态创建函数

如果通过一个函数动态创建更多的函数,可以参考这篇https://zhuanlan.zhihu.com/p/386276353

import sys
import types
from typing import Any, Callable, Mapping, Sequence
from inspect import Parameter, Signaturedef create_function_from_parameters(func: Callable[[Mapping[str, Any]], Any],parameters: Sequence[Parameter],documentation=None,func_name=None,func_filename=None):new_signature = Signature(parameters)  # Checks the parameter consistencydef pass_locals():return dict_func(locals())  # noqa: F821 TODOcode = pass_locals.__code__mod_co_argcount = len(parameters)mod_co_nlocals = len(parameters)mod_co_varnames = tuple(param.name for param in parameters)mod_co_name = func_name or code.co_nameif func_filename:mod_co_filename = func_filenamemod_co_firstlineno = 1else:mod_co_filename = code.co_filenamemod_co_firstlineno = code.co_firstlinenoif sys.version_info >= (3, 8):modified_code = code.replace(co_argcount=mod_co_argcount,co_nlocals=mod_co_nlocals,co_varnames=mod_co_varnames,co_filename=mod_co_filename,co_name=mod_co_name,co_firstlineno=mod_co_firstlineno,)else:modified_code = types.CodeType(mod_co_argcount,code.co_kwonlyargcount,mod_co_nlocals,code.co_stacksize,code.co_flags,code.co_code,code.co_consts,code.co_names,mod_co_varnames,mod_co_filename,mod_co_name,mod_co_firstlineno,code.co_lnotab)default_arg_values = tuple(p.default for p in parameters if p.default != Parameter.empty) #!argdefs "starts from the right"/"is right-aligned"modified_func = types.FunctionType(modified_code, {'dict_func': func, 'locals': locals}, name=func_name, argdefs=default_arg_values)modified_func.__doc__ = documentationmodified_func.__signature__ = new_signaturereturn modified_funcdef foo(arg):print(arg)return "x"f = create_function_from_parameters(func=foo,parameters=[Parameter('x', Parameter.POSITIONAL_OR_KEYWORD)],documentation="some doc",func_name="bar",func_filename="main.py",
)print(f('xxx'))

等价于

def bar(a):"""some doc"""foo({"x":a})
f = bar

参考博客https://www.cnblogs.com/fireblackman/p/16192027.html
参考博客https://www.cnblogs.com/olivetree123/p/5067685.html

相关内容

热门资讯

demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...