python笔记76-types.FunctionType 动态创建函数

news2024/11/30 6:46:18

前言

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

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

FunctionType 使用

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

from types import FunctionType, MethodType


def func():
    print("hello")


class Demo:
    x = 1

    def fun(self):
        print(self.x)

    @staticmethod
    def fun2():
        print("f2")


print(type(func))  # <class 'function'>
x = Demo()
print(type(x.fun))  # <class 'method'>
print(type(x.fun2))  # <class 'function'>

# 判断是函数还是方法
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 types


def foobar():
    return "foobar"


dynamic_fun = types.FunctionType(foobar.__code__, {})
print(dynamic_fun())  # foobar

配合compile函数 创建函数

使用示例

import types

f = """
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, Signature


def 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 consistency

    def pass_locals():
        return dict_func(locals())  # noqa: F821 TODO

    code = 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_name
    if func_filename:
        mod_co_filename = func_filename
        mod_co_firstlineno = 1
    else:
        mod_co_filename = code.co_filename
        mod_co_firstlineno = code.co_firstlineno

    if 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__ = documentation
    modified_func.__signature__ = new_signature
    return modified_func


def 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/48937.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中国互联网综合实力100强:猿辅导第39

11月2日&#xff0c;中国互联网企业综合实力指数发布会暨百家企业高峰论坛在厦门成功举办。发布会上&#xff0c;中国互联网协会正式发布了《中国互联网企业综合实力指数&#xff08;2022&#xff09;》以及2022年中国互联网综合实力前百家企业榜单。 北京猿力教育科技有限公司…

腾讯基础面

传送门1. 有了解过C吗&#xff1f;接受转语言吗&#xff1f;2. 有没有了解过一些框架的底层原理、底层优化、数据库的索引优化3. 了解过哪些Map&#xff0c;可以从底层简单说下嘛&#xff1f;4. 你项目中是如何去实现幂等性的&#xff1f;5. RPC的协议讲一讲&#xff0c;怎么处…

开源共建 | TIS整合数据同步工具ChunJun,携手完善开源生态

TIS整合ChunJun实操 B站视频&#xff1a; https://www.bilibili.com/video/BV1QM411z7w5/?spm_id_from333.999.0.0 一、ChunJun 概述 ChunJun是一款易用、稳定、高效的批流统一的数据集成框架&#xff0c;可基于实时计算引擎Flink实现多种异构数据源之间的数据同步与计算&…

MySQL日志管理、备份与恢复

文章目录一、mysql常用日志1、概述①、错误日志②、二进制日志③、中继日志④、慢查询日志⑤、通用查询日志&#xff0c;用来记录MySQL的所有连接和语句&#xff0c;默认是关闭的2、数据库中查询日志状态①、查看二进制日志开启状态②、查看慢查询日志功能是否开启③、查看慢查…

FPGA书籍

1、Xilinx FPGA 权威设计指南 本书系统地介绍了Xilinx新一代集成开发环境Vivado 2018的设计方法、设计流程和具体实现。 全书共11章&#xff0c;内容包括Xilinx新一代UltraScale结构、Vivado集成设计环境导论、Vivado工程模式基本设计实现、Vivado非工程模式基本设计实现、创建…

Java-1129

Java8 新特性 速度更快代码更少&#xff08;lambda、stream&#xff09;强大的Stream API便于并行最大化减少空指针异常Optional 速度更快&#xff1a;对底层数据结构哈希map的优化 解释说明hashmap基本原理 hashmap本质是一个长度16的数组元素的键值对以key&#xff1a;valu…

强化学习实战——Motion Imitation环境配置+所遇问题(win10)

GitHub代码 注意&#xff1a;本篇环境配置是基于上一篇强化学习实战——OpenAI Gym环境配置实战演示&#xff08;win10&#xff09;环境的延续&#xff01;&#xff01;&#xff01; 一、环境配置 1&#xff09;下载requirements.txt内安装包 问题1&#xff1a;pybullet不能…

天图资本通过香港上市聆讯:上半年利润下滑24%,王永华为董事长

11月29日&#xff0c;深圳市天图投资管理股份有限公司&#xff08;下称“天图投资”&#xff09;通过港交所聆讯并在港交所递交了聆讯后资料集&#xff08;即招股书&#xff09;。相较于此前招股书&#xff0c;天图资本补充了截至2022年6月30日的财务数据等信息。 招股书显示&a…

哪个牌子蓝牙耳机打电话清晰?通话最清晰的蓝牙耳机推荐

随着蓝牙耳机的普及&#xff0c;越来越多的数码产品如笔记本、平板等都要配有蓝牙耳机&#xff0c;因此&#xff0c;市场对于大电视、多用途、高性能的无线蓝牙耳机的需求不断扩张。蓝牙耳机再这几年不但才音质上采用了最新的技术&#xff0c;通话方面也有改进&#xff0c;下面…

测试开发之路,我在大厂做测试这四年的感悟

开篇 当开始写这篇文章时候&#xff0c;才感受到人生如白驹过隙&#xff0c;4 年时间飞逝&#xff0c;自己也从一个初入职场小白到能肩负项目核心事务的测试开发。在这里&#xff0c;总结 4 年来的心智成长之路&#xff0c;也是借机互相交流&#xff0c;并无对错之争&#xff…

Java web 项目Tamcat在IDEA控制台输出乱码

遇到乱码问题怎么解决呢&#xff1f; 出现乱码其实就是编码格式有问题&#xff0c;设置一下呗&#xff0c;我们先查看一下编码格式&#xff0c;在改一下 1.查看编码格式 首选进入Tamcat安装的根目录 进入conf目录 找到logging.prooperties文件并打开 查看编码格式 编码格式为…

单机服务器docker搭建mysql5.7主从同步

1.首先使用docker安装mysql5.7 docker pull mysql:5.7 2.创建主库&#xff08;从3306映射一个3308端口&#xff09; docker run -d -p 3308:3306 -v /home/mysql-master/conf:/etc/mysql/conf.d -v /home/mysql-master/data:/var/lib/mysql -v /home/mysql-master/log:/var/lo…

启程,2022亚马逊云科技re:Invent Peter带来主题演讲

北京时间11月29日&#xff0c;2022亚马逊云科技re:Invent全球大会开幕首日&#xff0c;亚马逊云科技高级副总裁Peter DeSantis带来最新创新产品隆重登场&#xff0c;其间不乏计算、网络、算法及Serverless等最新功能特性。 网络协议创新&#xff1a;新产品 新理念 基于亚马逊…

MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制

一、准备工作 首先需要准备好环境&#xff0c;包含必要的软件&#xff0c;痞子衡的环境如下&#xff1a; 集成开发环境&#xff1a; MCUXpresso IDE_11.6.0_8187&#xff0c;点此下载软件开发包&#xff1a; SDK_2.12.1_EVK-MIMXRT1170&#xff08;Toolchain需包含MCUXpresso I…

这么卷,现在测试工程师要求会写工具了?

Fintech概念正受到不少互联网金融公司的热捧&#xff0c;主要是指代那些可用于撕裂传统金融服务方式的高新技术。越来越多的企业开辟了新的部门去研究各种各样能让自己产品增值的科技类产品。 尤其是在很多互联网金融公司&#xff0c;业务分析师BA(Business Analyst)&#xff…

【Linux】-- 初识操作系统

目录 一、冯诺依曼体系结构 二、操作系统 1.概念 2.为什么要有操作系统 三.操作系统 1.硬件层 2.驱动层 3.操作系统层 4.用户层 &#xff08;1&#xff09;用户层 &#xff08;2&#xff09;系统调用接口 &#xff08;3&#xff09;用户操作接口 四、如何管理 1…

C. Zero-Sum Prefixes Codeforces Round #833 (Div. 2)(前缀和+贪心)

传送门 题意&#xff1a; 给你一个长度为n的数组&#xff0c;里面包含a1,a2,a3...an n个元素&#xff0c; 当的时候&#xff0c;你可以将变成任意数字&#xff0c; 问你经过任意次操作后对于&#xff0c;它的前i项和为0的个数是最大是多少&#xff1f; 思路&#xff1a; …

27岁自学Python转行靠谱吗?入行晚吗?

前言 今年已经奔三的小编来给大家说说&#xff0c;之前自己也是在一个普通的二本院校上学&#xff0c;学的还是工商管理&#xff0c;毕竟读书的时候电视剧里面的主角都是工商管理的大佬。 不过在毕业之后就经历了社会的毒打&#xff0c;后面小编就想去换一个工作&#xff0c;…

[附源码]计算机毕业设计springboot交通事故档案管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

jsp192ssm驾校报名预约管理系统

目 录 汽车驾校管理系统设计与实现 I 摘 要 I ABSTRACT I 目 录 III 第1章 绪论 3 1.1开发背景 3 1.2开发意义 3 1.3研究内容 3 第2章 主要技术和工具介绍 3 2.1SSM 框架 错误&#xff01;未定义书签。 2.1.1. Spring 框架 3 2.1.2 SpringS…