示例函数
为了开发类型检查,我们需要的是一个简单的功能测试。欧几里德算法是一个很好的例子:

DEF GCD(A,B):

“”“返回a和b的最大周一除数。“”‘
一个= ABS(a)中
B = ABS(B)
如果一个 A,B = B,A
而b != 0:
A,B = B,A%B
返回

在上面的例子中,参数a和b,并且返回值应该是int类型的。将有望作为类型注释来表达的功能,功能注解的Python 3的新特性。接着,类型检查机制将被实现为一个装饰,代码的第一行的带注释版本是:

DEF GCD(一个:INT,B:INT) - > INT:

使用“GCD。__annotations__“你可以得到一个包含注释的词典:

>>> GCD。__annotations__
{ ’回归‘: , ’B‘: , ’一个‘: }
>>> GCD。__annotations __ [ ’一‘]


应当指出的是,票据保存在钥匙“回归”较低的返回值。这是可能的,因为“回归”是一个关键词,它不能被用来作为一个有效的参数名称。
检查返回值的类型
返回值注释存储在辞典“__annotations__”中的“返回”键。我们将使用这个值来检查(假设票据存在)的返回值。我们将参数传递给一个原始的,如果存在注解,我们会在一个价值验证其注释类型:

DEF类型检查(F):
高清封装(* ARGS,** kwargs):
结果= F(*指定参数时,** kwargs)
return_type = F。__annotations__。得到(“回报”,无)
如果return_type而不是isinstance(结果,return_type):
提高RuntimeError( “{}应该返回{}”。格式(F。__name__,return_type。__名称__))
返回结果
返回包装

我们可以用“一” GCD返回值来测试上面的代码替换功能:

回溯(最近通话最后一个):
文件“typechecker。PY”,第9行,在
GCD(1,2)
文件“typechecker。PY”,第5行,在包装
提高RuntimeError( “{}应该返回{}”。格式(F。__name__,return_type。__名称__))
RuntimeError:GCD应该返回INT

从上面的结果,确实是我们检查类型的返回值。
检查参数类型
存在于“co_varnames”的参数属性代码相关联的对象的功能,在我们的例子中“GCD。__码__。co_varnames“。元组包含所有局部变量,参数的名称和启动元组的参数存储在“co_nlocals”中的数。我们需要遍历所有变量,包括指数在内,并获得参数“ARGS”的参数值,最后它的类型检查。
得到下面的代码:

DEF类型检查(F):
高清封装(* ARGS,** kwargs):
对于i,精氨酸在枚举(参数[:F。__码__。co_nlocals]):
名称= F。__码__。co_varnames [I]
EXPECTED_TYPE = F。__annotations__。得到(名称,无)
EXPECTED_TYPE如果不isinstance(阿根廷,EXPECTED_TYPE):
提高RuntimeError( “{}应该是类型{}的{}中指定”。格式(名称,EXPECTED_TYPE。__name__,类型(ARG)。__名称__))
结果= F(*指定参数时,** kwargs)
return_type = F。__annotations__。得到(“回报”,无)
如果return_type而不是isinstance(结果,return_type):
提高RuntimeError( “{}应该返回{}”。格式(F。__name__,return_type。__名称__))
返回结果
返回包装

在上述循环中,i为0的数组参数ARGS开始索引处,ARG值是一个字符串,它包括。您可以使用“F。__码__。co_varnames [I]“来读取参数的名称。类型检查代码完全检查相同的返回类型(包括异常的错误消息)。
要关键字参数类型检查,我们需要遍历参数kwargs。这时,几乎是相同的类型检查第一个循环:

对于名称,精氨酸在kwargs。项目():
EXPECTED_TYPE = F。__annotations__。得到(名称,无)
EXPECTED_TYPE如果不isinstance(阿根廷,EXPECTED_TYPE):
提高RuntimeError( “{}应该是类型{}的{}中指定”。格式(名称,EXPECTED_TYPE。__name__,类型(ARG)。__名称__))

装饰码获得如下:

DEF类型检查(F):
高清封装(* ARGS,** kwargs):
对于i,精氨酸在枚举(参数[:F。__码__。co_nlocals]):
名称= F。__码__。co_varnames [I]
EXPECTED_TYPE = F。__annotations__。得到(名称,无)
EXPECTED_TYPE如果不isinstance(阿根廷,EXPECTED_TYPE):
提高RuntimeError( “{}应该是类型{}的{}中指定”。格式(名称,EXPECTED_TYPE。__name__,类型(ARG)。__名称__))
对于名称,精氨酸在kwargs。项目():
EXPECTED_TYPE = F。__annotations__。得到(名称,无)
EXPECTED_TYPE如果不isinstance(阿根廷,EXPECTED_TYPE):
提高RuntimeError( “{}应该是类型{}的{}中指定”。格式(名称,EXPECTED_TYPE。__name__,类型(ARG)。__名称__))
结果= F(*指定参数时,** kwargs)
return_type = F。__annotations__。得到(“回报”,无)
如果return_type而不是isinstance(结果,return_type):
提高RuntimeError( “{}应该返回{}”。格式(F。__name__,return_type。__名称__))
返回结果
返回包装

该代码是写在一个类型检查功能将使代码更清晰。为了简化代码,我们修改错误消息,并且当返回值是无效的类型,将用于这些错误信息。我们也可以用一个方法包装functools模块的一些属性复制到包装的包装功能(这使得它看起来更像原来的功能包装):

DEF类型检查(F):
高清do_typecheck(姓名,ARG):
EXPECTED_TYPE = F。__annotations__。得到(名称,无)
EXPECTED_TYPE如果不isinstance(阿根廷,EXPECTED_TYPE):
提高RuntimeError( “{}应该是类型{}代替{}”。格式(名称,EXPECTED_TYPE。__name__,类型(ARG)。__名称__))

@functools。包裹物(F)
高清封装(* ARGS,** kwargs):
对于i,精氨酸在枚举(参数[:F。__码__。co_nlocals]):
do_typecheck(F。__码__。co_varnames [I],ARG)
对于名称,精氨酸在kwargs。项目():
do_typecheck(姓名,ARG)

结果= F(*指定参数时,** kwargs)

do_typecheck( ’回归',结果)
返回结果
返回包装

结论
注释是在Python 3的新元素,使用本文中的例子很常见,你可以想像很多具体领域的应用。虽然上面的实现代码并不能满足该产品的实际需求,但它最初是作为概念对象的证明。以下可以改进:
额外的处理参数(在args意想不到项)
默认类型检查
对多种类型的支持
支持模板类型(例如,INT类型列表)

本文链接:python3怎样检查网站构建的技术类型

您可能也会喜欢

友情链接:

经文 大悲咒注音 心经唱诵