如何为dictview类型添加注解以满足mypy类型检查?
精准识别原生字典视图类型的类型检查问题
先看dict_keys的实例验证代码:
dict_keys = type({}.keys()) print(dict_keys) # <class 'dict_keys'> assert isinstance({}.keys(), dict_keys)
按Python官方文档说明,.keys()、.values()和.items()返回的都是字典视图(文档中称为dictview),但在CPython的实际实现中,并没有一个统一的dictview基类,三个视图类型都是直接继承自object:
# Python 3.7-3.11 输出一致 print(dict_keys.mro()) # [<class 'dict_keys'>, <class 'object'>] print({}.values().__class__.mro()) # [<class 'dict_values'>, <class 'object'>] print({}.items().__class__.mro()) # [<class 'dict_items'>, <class 'object'>]
需求背景
需要实现仅接受原生字典视图对象,拒绝仿造的类字典视图对象(设计上不允许鸭子类型匹配)。
当前遇到的问题
如果直接通过type({}.keys())获取类型并用于检查,mypy会抛出类型注解缺失的错误:
dict_keys = type({}.keys()) # main.py:1: error: Need type annotation for "dict_keys" [var-annotated]
尝试用最接近的公开类型types.MappingProxyType来做类型注解也不可行——它带有额外的映射方法,和原生字典视图并不等价,同时会触发类型不兼容错误:
from types import MappingProxyType from typing import Type dict_keys: Type[MappingProxyType] = type({}.keys()) # error: Incompatible types in # assignment (expression has type "Type[dict_keys[<nothing>, <nothing>]]", # variable has type "Type[MappingProxyType[Any, Any]]") [assignment] x: dict_keys # error: Variable "__main__.dict_keys" is not valid as a type [valid-type] len(x)
第一个错误说明mypy其实能识别dict_keys类型的存在,但仍强制要求手动添加注解;第二个错误属于次要问题。
疑问
有没有我忽略的直观解决方案?还是应该向mypy仓库提交issue?(注:不想用Any来规避,这违背了类型检查的初衷)
内容的提问来源于stack exchange,提问作者krassowski
相关产品推荐
相关产品推荐

