在Python中,没有可以在运行时简化函数定义的语法糖。然而,这并不意味着它不可能或难以实现。fromtypesimportFunctionTypefoo_code=compile('deffoo():return"bar"',"","exec")foo_func=FunctionType(foo_code.co_consts[0],globals(),"foo")print(foo_func())output:bardissection逐行检查代码,您会发现语言/解释器屏障是多么脆弱。>>>fromtypesimportFunctionTypePython文档通常不会列出不适用于手动创建的类的特征(这是完全合理的)。解决这个问题的方法有3种:help()、inspect(无法查看内置方法),最后的解决办法,就是查看CPython源码。在这种情况下,help()和inspect都可以完成这项工作,但查看实际的源代码将揭示有关数据类型的更多细节。>>>frominspectimportsignature>>>signature(FunctionType)代码里面是一个PyCode对象,对外开放为类型.代码类型。非内置方法有一个__code__属性,它保存着相应的代码对象。Types.CodeType对象可以在运行时使用内置的compile()方法创建。globals如果一个函数引用了一个未在本地定义的变量,但作为参数传入,由默认参数值提供,或通过闭包上下文提供,它会在globals字典中查找。内置的globals()方法返回对当前模块的全局符号表的引用,因此可用于提供始终与当前表的状态一致的字典。也可以传递任何其他字典(FunctionType((lambda:bar).__code__,{"bar":"baz"},"foo")()=="baz")。name(可选)控制返回函数的__name__属性。仅对lambda(由于匿名而通常没有名称)和重命名函数真正有用。argdefs(可选)提供了一种通过传入包含任何类型对象的元组来提供默认参数值(defffoo(bar="baz"))的方法。(FunctionType((lambdabar:bar).__code__,{},"foo",(10,))()==10)。闭包(可选)(如果需要在CPython(PyPy、Jython等)以外的PythonVM中执行,则可能不应该被触及,因为它在很大程度上依赖于实现细节)。单元格对象的元组。创建单元格对象并不完全直接,因为需要调用CPython内部结构,但是有一个库可以使它更加方便:exalt(无耻的广告)。(译注:本库为作者开发。)>>>foo_code=compile('deffoo():return"bar"',"","exec")compile()是内置方法,所以同时也是有据可查的。使用exec模式是因为定义函数需要多条语句。>>>foo_func=FunctionType(foo_code.co_consts[0],globals(),"foo")聚合所有内容并将动态创建的函数分配给变量。上一行代码编译成的函数成为生成代码对象的第一个常量,所以仅仅指向foo_code是不够的。这是exec模式的直接结果,因为生成的代码对象可以包含多个常量。>>>print(foo_func())可以像调用任何其他函数一样调用动态生成的函数。最后,除了做实验,很少有场景需要用到动态创建功能。玩转Python的内部结构是深入学习这门语言的好方法。如果需要,可以毫不费力地跨越口译员/语言的界限。还是一如既往:不要滥用语言(好吧,一点点也行吧?)以上就是本次分享的全部内容,想要了解更多python知识,请前往公众号:Python编程学习圈子,送“J”即可免费领取,每日干货分享