types.FunctionType 创建函数有2种方式:
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个参数
import typesdef foobar():return "foobar"dynamic_fun = types.FunctionType(foobar.__code__, {})
print(dynamic_fun()) # foobar
使用示例
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