是否有针对输入类型的规范“isinstance”实现?
Is there a canonical “isinstance” implementation for typing types?
你不能在 isinstance
检查中使用像 Dict[str, int]
这样的 typing 类型:
Python 3.7.6 (default, Dec 30 2019, 19:38:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from typing import Dict
In [2]: myvar = {"a": 1}
In [3]: isinstance(myvar, Dict[str, int])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-a8fee57141ae> in <module>
----> 1 isinstance(myvar, Dict[str, int])
然而,任何进行类型检查的库都需要能够做类似 isinstance(myvar, Dict[str, int])
的事情(...我意识到它应该被称为不同于 isinstance
的东西,这是不完全一样)
我觉得用于打字的等效函数一定存在于某处,也许在 mypy 项目中? (不过里面代码比较复杂,我至今没找到)
除了 mypy 之外还有很多项目需要这个,像 pydantic for example, and AFAICT they all have complicated hand-rolled implementations and it seems like there are lots of edge cases (or just… ‘cases’) which have to be enumerated and covered. This leads to bugs/limited type recognition e.g. https://github.com/bloomberg/attrs-strict/issues/27
这样的库
似乎需要规范地实现此功能。是否已经存在我没有找到的地方?
我给你一个来自 Python stdlib 的激励性例子:
https://docs.python.org/3/library/functools.html#functools.singledispatch
For functions annotated with types, the decorator will infer the type of the first argument automatically:
>>> @fun.register
... def _(arg: int, verbose=False):
... if verbose:
... print("Strength in numbers, eh?", end=" ")
... print(arg)
...
>>> @fun.register
... def _(arg: list, verbose=False):
... if verbose:
... print("Enumerate this:")
... for i, elem in enumerate(arg):
... print(i, elem)
嗯,这很酷。但这是作弊,因为现在通常我们不会使用内置的 list
来注释第二个函数,而是使用 List[str]
之类的东西......那是行不通的,因为 singledispatch
是只是做一个天真的 isinstance
检查,它不能处理类型泛型。所以 singledispatch
并不像它声称的那样真正支持按类型注释进行调度。
不,没有此类规范检查。正如评论者所说,为静态类型检查引入了类型,我认为许多核心开发人员认为它应该保持这种状态。
我能想到的最接近的东西是 pydantic 的 parse_obj_as
。它的不同之处在于它试图将对象强制转换为特定类型,如果失败则引发错误,但它非常接近。
用法:
from pydantic import parse_obj_as
from typing import Dict
parse_obj_as(Dict[str, int], {'xxx': 1, 'yyy': 2})
#> {'xxx': 1, 'yyy': 2}
parse_obj_as(Dict[str, int], {'xxx': 1, 123: '12'})
#> {'xxx': 1, '123': 12}
parse_obj_as(Dict[str, int], ['not a dict'])
#> ValidationError: 1 validation error for ParsingModel[Dict[str, int]]
#> __root__
#> value is not a valid dict (type=type_error.dict)
文档here.
注意:我构建的是pydantic,所以我有点偏颇。
你不能在 isinstance
检查中使用像 Dict[str, int]
这样的 typing 类型:
Python 3.7.6 (default, Dec 30 2019, 19:38:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from typing import Dict
In [2]: myvar = {"a": 1}
In [3]: isinstance(myvar, Dict[str, int])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-a8fee57141ae> in <module>
----> 1 isinstance(myvar, Dict[str, int])
然而,任何进行类型检查的库都需要能够做类似 isinstance(myvar, Dict[str, int])
的事情(...我意识到它应该被称为不同于 isinstance
的东西,这是不完全一样)
我觉得用于打字的等效函数一定存在于某处,也许在 mypy 项目中? (不过里面代码比较复杂,我至今没找到)
除了 mypy 之外还有很多项目需要这个,像 pydantic for example, and AFAICT they all have complicated hand-rolled implementations and it seems like there are lots of edge cases (or just… ‘cases’) which have to be enumerated and covered. This leads to bugs/limited type recognition e.g. https://github.com/bloomberg/attrs-strict/issues/27
这样的库似乎需要规范地实现此功能。是否已经存在我没有找到的地方?
我给你一个来自 Python stdlib 的激励性例子:
https://docs.python.org/3/library/functools.html#functools.singledispatch
For functions annotated with types, the decorator will infer the type of the first argument automatically:
>>> @fun.register
... def _(arg: int, verbose=False):
... if verbose:
... print("Strength in numbers, eh?", end=" ")
... print(arg)
...
>>> @fun.register
... def _(arg: list, verbose=False):
... if verbose:
... print("Enumerate this:")
... for i, elem in enumerate(arg):
... print(i, elem)
嗯,这很酷。但这是作弊,因为现在通常我们不会使用内置的 list
来注释第二个函数,而是使用 List[str]
之类的东西......那是行不通的,因为 singledispatch
是只是做一个天真的 isinstance
检查,它不能处理类型泛型。所以 singledispatch
并不像它声称的那样真正支持按类型注释进行调度。
不,没有此类规范检查。正如评论者所说,为静态类型检查引入了类型,我认为许多核心开发人员认为它应该保持这种状态。
我能想到的最接近的东西是 pydantic 的 parse_obj_as
。它的不同之处在于它试图将对象强制转换为特定类型,如果失败则引发错误,但它非常接近。
用法:
from pydantic import parse_obj_as
from typing import Dict
parse_obj_as(Dict[str, int], {'xxx': 1, 'yyy': 2})
#> {'xxx': 1, 'yyy': 2}
parse_obj_as(Dict[str, int], {'xxx': 1, 123: '12'})
#> {'xxx': 1, '123': 12}
parse_obj_as(Dict[str, int], ['not a dict'])
#> ValidationError: 1 validation error for ParsingModel[Dict[str, int]]
#> __root__
#> value is not a valid dict (type=type_error.dict)
文档here.
注意:我构建的是pydantic,所以我有点偏颇。