Python 类型验证

Posted

技术标签:

【中文标题】Python 类型验证【英文标题】:Python typing validation 【发布时间】:2018-08-10 13:07:45 【问题描述】:

我想在我的项目中实现 Python 3.6 类型注释的验证。

我有一个方法使用__annotations__ dict 来检查类的所有属性是否具有正确的值。它适用于intstrbool 等基本类型,但对于typing.Uniontyping.Optional(也是一个联合)等更复杂的元素则无效。 失败是由抛出TypeErrorUnion 对象中的isinstance() 方法引起的。我什至找不到确保注释是联合的方法,因此我无法验证值是否符合类型。

typing 模块没有任何解决方案。有没有办法验证指定的变量是否符合typing.Union

【问题讨论】:

【参考方案1】:

是的。 isinstanceissubclass 前一段时间是 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 类型验证的主要内容,如果未能解决你的问题,请参考以下文章

类型错误:只有长度为 1 的数组可以转换为 Python 标量,同时使用 Kfold 交叉验证

python的random模块(生成验证码)

python如何判断类型

Python可变类型与不可变类型

Python可变类型与不可变类型

Python可变类型与不可变类型