Python函数注释简易教程

治疗白癜风最新最佳最好的方法 https://m-mip.39.net/czk/mipso_7375991.html

Python函数注释是在PEP引入的,其主要目的是给函数形参和返回值添加可选元数据。

两点重要的信息

函数注释可选可添加任意Python表达式,但是Python本身并不会对表达式做处理,也不具有任何意思

函数注释语法如下:

defannotation(param1:"第一个函数注释",param2:"第二个函数注释")-"返回值函数注释":...pass...annotation.__annotations__{param1:第一个函数注释,param2:第二个函数注释,return:返回值函数注释}

我们可以通过函数对象的__annotation__属性来获取所有的注释,其中有一个特别的key是return专门用来存放返回值函数注释。

函数注释可以被用来实现很多功能:

类型检测谓词逻辑IDE类型辅助

下面我们利用函数注释实现一个简单的谓词逻辑功能。

我们先创建一个函数,并给两个参数添加_谓词注释_。

defrepeat(times:times0andtimes10,name:len(name)5)-str:returnname*timestimes必须大于0并且小于10name长度必须大于5

我们可以直接运行该函数,但是Python不会解释注释,所以注释并没有效果。接下来我们来学习如何优雅的访问这些注释。

frominspectimportsignaturesig=signature(repeat)forparam_nameinsig.parameters:print(f"{sig.parameters[param_name]}")#times:times0andtimes10#name:len(name)5

我们可以利用signature来访问函数参数,注意signature.parameters是一个有序字典,按照参数列表的顺序访问参数。

接下来我们要使用装饰器语法来定义一个可以在运行时访问实参的wrapper函数。

defparameter_predicate(f):defwrapper(*args,**kwargs):forarginargs:print(arg)forkey,valueinkwargs:print(key,value)returnf(*args,**kwargs)returnwrapper

parameter_predicatedefrepeat(times:times0andtimes10,name:len(name)5)-str:returnname*timesrepeat(1,"abcde")#1#abcde

现在唯一欠缺的就是如何执行注释中的Python表达式,我们使用eval内置函数。

globals={}locals={"name":"Hello,World"}eval("print(name)",globals,locals)

eval函数可以执行任意的Python片段,其中出现的变量会通过globals和locals变量表查询,如果没有查询到则会报错。

现在我们有了实现谓词解释器的所有工具。我们可以组合这些代码如下所示。

由于Python中参数可以通过位置或者关键字的形式传入,所以args和kwargs都需要处理,我们将实参值做为locals变量表传给eval,并且将失败的失败的谓词逻辑放入failures数组。

frominspectimportsignaturedefparameter_predicate(f):sig=signature(f)defwrapper(*args,**kwargs):params=[paramforparaminsig.parameters]failures=[]foriinrange(0,len(args)):param=sig.parameters[params[i]]value=args[i]locals={param.name:value}globals={}ifnoteval(param.annotation,globals,locals):failures.append({"name":param.name,"condition":param.annotation.format(param.name),"context":{param.name:value}})foriinrange(len(args),len(args)+len(kwargs)):param=sig.parameters[params[i]]value=kwargs[param.name]locals={param.name:value}globals={}ifnoteval(param.annotation,globals,locals):failures.append({"name":param.name,"condition":param.annotation.format(param.name),"context":{param.name:value}})iflen(failures)0:raiseRuntimeError(f"{failures}")returnf(*args,**kwargs)returnwrapper

parameter_predicatedefrepeat(times:times0andtimes10,name:len(name)5)-str:returnname*timesrepeat(1,"abcde")#RuntimeError:[{name:name,condition:len(name)5,context:{name:abcde}}]print(repeat(0,"abcdef"))#RuntimeError:[{name:times,condition:times0andtimes10,context:{times:0}}]

通过定义并处理函数注释,我们实现了一个简单的谓词解释器,帮助我们附加一些谓词条件到形参上。当然通过自定义一些语法,我们可以使谓词更加复杂具有更多功能。

预览时标签不可点收录于话题#个上一篇下一篇

转载请注明:http://www.sonphie.com/lcbx/14534.html

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 网站简介| 发布优势| 服务条款| 隐私保护| 广告合作| 网站地图| 版权申明

    当前时间: