使用Python dicts进行静态类型分析
有人能解释为什么这段代码虽然有效,但会让mypy静态分析器以多种方式抱怨:使用Python dicts进行静态类型分析,python,mypy,Python,Mypy,有人能解释为什么这段代码虽然有效,但会让mypy静态分析器以多种方式抱怨: ranges = dict() ranges['max'] = 0 ranges['services'] = [] ranges['services'].append('a') 即: 错误:赋值中的类型不兼容(表达式的类型为“List[]”,目标的类型为“int”) 错误:“int”没有属性“append” 如果我只是在ranges:dict=dict()的初始变量中添加一个类型提示,它就可以正常工作了 我不明白为什
ranges = dict()
ranges['max'] = 0
ranges['services'] = []
ranges['services'].append('a')
即:
错误:赋值中的类型不兼容(表达式的类型为“List[]”,目标的类型为“int”)
错误:“int”没有属性“append”
如果我只是在ranges:dict=dict()的初始变量中添加一个类型提示,它就可以正常工作了
我不明白为什么静态分析器不能自己解决这个问题,特别是当我首先使用dict
关键字初始化dict时。字典通常用作键控集合,最重要的操作是查找与任意键相关的值。通常在字典中,每个键都有相同的类型,每个值都有相同的类型;如果值是异构的,那么表达式ranges[key]
不一定有特定的类型(尽管可以将其表示为并集)
在代码中,静态分析器试图推断字典的类型。它期望的类型为Dict[K,V]
形式,其中K
和V
尚未确定。第一个赋值ranges['max']=0
给出了关于这两个未知数的信息:K
似乎是str
,V
似乎是int
。因此,此时,范围
被推断为类型Dict[str,int]
接下来的两行给出了错误,因为空列表不能用作Dict[str,int]
中的值,并且Dict[str,int]
中的值没有append
方法
显式类型注释ranges:dict=dict()
通过指定这是一个异类字典来推翻默认行为,因此值不必都具有相同的类型。给定该信息,静态分析器不会假设因为其中一个值是int
,它们都必须是int
s.因为您没有提供任何注释,mypy
必须尝试推断类型。它可以做出一些选择:
ranges=dict()
表示range:dict[Any,Any]
这将接受您的所有代码。它还可以接受范围['services'].keys()
或任何其他操作,因为它会删除所有类型信息
范围['max']=0
意味着范围:Dict[str,int]
这是mypy
选择的内容。它拒绝任何非整数的键,具体到列表
ranges['services']=[]
意味着range:Dict[str,list]
这只接受您的范围['services']
字段。既然范围['max']
不是列表,那么它就无效了
范围['max']=0
和范围['services']=[]
意味着范围:Dict[str,Union[int,list]
这接受值的赋值。它拒绝ranges['services'].append('a')
,因为ranges['services']
可能是int
基本上,这些都不起作用。使用普通的Dict[K,V]
,您的代码无法正确键入
您可以使用显式注释范围
。由于dict
通常不限于静态键值对,mypy
本身不会推断出这一点
class Ranges(TypedDict):
max: int
services: List[str]
ranges: Ranges = dict()
很好,简洁的回答。谢谢。