Python 类型验证
Posted
技术标签:
【中文标题】Python 类型验证【英文标题】:Python typing validation 【发布时间】:2018-08-10 13:07:45 【问题描述】:我想在我的项目中实现 Python 3.6 类型注释的验证。
我有一个方法使用__annotations__
dict 来检查类的所有属性是否具有正确的值。它适用于int
、str
或bool
等基本类型,但对于typing.Union
或typing.Optional
(也是一个联合)等更复杂的元素则无效。
失败是由抛出TypeError
的Union
对象中的isinstance()
方法引起的。我什至找不到确保注释是联合的方法,因此我无法验证值是否符合类型。
typing
模块没有任何解决方案。有没有办法验证指定的变量是否符合typing.Union
?
【问题讨论】:
【参考方案1】:是的。 isinstance
和 issubclass
前一段时间是 killed,用于类似 Union
的情况。
正如in a comment on the issue by GvR 所述,这个想法是实现您自己的issubclass/isinstance
版本,它使用一些附加到类型的额外元数据:
>>> Union[int, str].__args__
(int, str)
>>> Union[int, str].__origin__
typing.Union
__args__
和 __origin__
从 Python 3.6.3 开始提供。它们可能不在早期版本中,因为typing 仍然是临时的。
在充实自省类型的内部接口并从临时状态中键入毕业生之前,您应该预料到由于 API 的变化而损坏。
【讨论】:
【参考方案2】:您可以在这里输入Unions:pydantic
【讨论】:
Pydantic 使用来自typing
模块的相同 Union
类 ...【参考方案3】:
在使用isinstance()
之前,你需要检查注解是否是来自模块typing
的注解。
我是这样做的:
def _is_instance(self, value: Any, annotation: type) -> bool:
str_annotation = str(annotation)
if self._is_typing_alias(str_annotation):
if self._is_supported_alias(str_annotation):
is_instance = self._get_alias_method(str_annotation)
if is_instance is not None:
return is_instance(value, annotation)
exception = TypeError('Alias is not supported!')
self._field_errors.append(TypingValidationError(
value_repr=get_value_repr(value), value_type=type(value),
annotation=annotation, exception=exception
))
return False
return super()._is_instance(value, annotation)
更多详情:https://github.com/EvgeniyBurdin/validated_dc/blob/master/validated_dc.py
【讨论】:
以上是关于Python 类型验证的主要内容,如果未能解决你的问题,请参考以下文章