我想在我的项目中实现Python 3.6类型注释的验证。
我有一个使用fd_retrieve
dict来检查类的所有属性是否都具有正确值的方法。它适用于while (1) {
my $msg = <STDIN>;
$socket->send($msg);
my $struct = fd_retrieve($socket);
print Dumper($struct);
}
,__annotations__
或int
等基本类型,但对于str
或bool
(也是联盟)等更复杂的元素却失败了。
失败是由引发typing.Union
的{{1}}对象中的typing.Optional
方法引起的。我甚至找不到确保注释是联盟的方法,因此我无法验证值是否符合类型。
isinstance()
模块没有任何解决方案。有没有办法验证指定的变量是否符合Union
?
答案 0 :(得分:0)
是。对于像isinstance
这样的案例,前一段时间issubclass
和Union
为killed。
同样声明in a comment on the issue by GvR的想法是实现您自己的issubclass/isinstance
版本,该版本使用附加到类型的一些额外元数据:
>>> Union[int, str].__args__
(int, str)
>>> Union[int, str].__origin__
typing.Union
从Python 3.6.3开始, __args__
和__origin__
可用 。它们可能不在早期版本中,因为typing仍然是临时的。
在内省类型的内部接口充实并从临时状态键入毕业生之前,您应该期望由于API的更改而导致破坏。
答案 1 :(得分:0)
在使用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
答案 2 :(得分:0)