MyPy:如何为将传入isinstance()的参数标注类型
为兼容isinstance的参数标注类型的正确方式
你完全不需要用Any,直接用MyPy/Typeshed提供的_ClassInfo类型就好,这是最准确的选择,具体理由和做法如下:
直接导入使用
_ClassInfo
虽然_ClassInfo名字带单下划线,看起来像内部类型,但它是Typeshed(Python标准库的类型存根集合)中专门为isinstance第二个参数定义的标准类型,已经完美处理了递归嵌套的元组结构(比如tuple[type, tuple[type, ...]]这类情况),MyPy完全认可这个标注。
示例代码:from typing import _ClassInfo, Any def my_pred(val: Any, types: _ClassInfo) -> bool: return isinstance(val, types)别用
Any
用Any会直接丢失类型检查的意义——MyPy无法帮你验证传入的types参数是否符合isinstance的要求,比如传入字符串、数字这类非法参数时,不会给出任何错误提示。关于下划线类型的顾虑
单下划线开头的命名只是PEP8里的“内部元素”约定,但在类型标注场景下,_ClassInfo是公开可用的标准类型,只要你使用的MyPy版本依赖的Typeshed还保留这个定义,就可以稳定使用,不需要担心兼容性问题。
如果你实在不想用带下划线的类型,手动写递归类型(比如Union[type, Tuple[Union[type, Tuple[...]], ...]])是可行的,但MyPy对这类手动递归类型的支持很差,会出现误判,远不如直接用_ClassInfo靠谱。
内容的提问来源于stack exchange,提问作者Tab Atkins-Bittner
相关产品推荐
相关产品推荐

