Python类型注解理解问题
Python Type Annotation Understanding Problem
我对 python 类型注释有一点理解上的问题。考虑以下用于将字典转换为标准化格式的函数
from __future__ import annotations # needed for type annotations in > python 3.7
from typing import Dict, List, Union
class Producer(object):
pass
def normalize_producers(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key in producers.keys():
if isinstance(producers[key], list):
normalized_dict[key] = producers[key]
else:
normalized_dict[key] = [producers[key]]
return normalized_dict
此示例导致分配 normalized_dict
:
的类型问题
Argument of type "Producer | List[Producer]" cannot be assigned to parameter "v" of type "List[Producer]" in function "__setitem__"
Type "Producer | List[Producer]" cannot be assigned to type "List[Producer]"
"Producer" is incompatible with "List[Producer]"
Argument of type "list[Producer | List[Producer]]" cannot be assigned to parameter "v" of type "List[Producer]" in function "__setitem__"
TypeVar "_T@list" is invariant
Type "Producer | List[Producer]" cannot be assigned to type "Producer"
"List[Producer]" is incompatible with "Producer"
但是,当我使用临时列表并检查该列表的类型时,没有出现类型问题:
def normalize_producers_save(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key in producers.keys():
templist = producers[key]
if isinstance(templist, list):
normalized_dict[key] = templist
else:
normalized_dict[key] = [templist]
return normalized_dict
这是否意味着,虽然我将 producers
的值指定为 Producer
或 List[Producer]
类型,但 if isinstance(producers[key], list):
不会导致 producers[key]
总是类型列表?我不明白,第一个版本的功能有什么问题。
这是 mypy
中已知的 issue,它不会像 dict_var[key]
那样缩小索引表达式的类型。作为解决方法,您可以为字典值使用显式变量:
from __future__ import annotations # needed for type annotations in > python 3.7
from typing import Dict, List, Union
class Producer(object):
pass
def normalize_producers(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key, value in producers.items():
if isinstance(value, list):
normalized_dict[key] = value
else:
normalized_dict[key] = [value]
return normalized_dict
我对 python 类型注释有一点理解上的问题。考虑以下用于将字典转换为标准化格式的函数
from __future__ import annotations # needed for type annotations in > python 3.7
from typing import Dict, List, Union
class Producer(object):
pass
def normalize_producers(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key in producers.keys():
if isinstance(producers[key], list):
normalized_dict[key] = producers[key]
else:
normalized_dict[key] = [producers[key]]
return normalized_dict
此示例导致分配 normalized_dict
:
Argument of type "Producer | List[Producer]" cannot be assigned to parameter "v" of type "List[Producer]" in function "__setitem__"
Type "Producer | List[Producer]" cannot be assigned to type "List[Producer]"
"Producer" is incompatible with "List[Producer]"
Argument of type "list[Producer | List[Producer]]" cannot be assigned to parameter "v" of type "List[Producer]" in function "__setitem__"
TypeVar "_T@list" is invariant
Type "Producer | List[Producer]" cannot be assigned to type "Producer"
"List[Producer]" is incompatible with "Producer"
但是,当我使用临时列表并检查该列表的类型时,没有出现类型问题:
def normalize_producers_save(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key in producers.keys():
templist = producers[key]
if isinstance(templist, list):
normalized_dict[key] = templist
else:
normalized_dict[key] = [templist]
return normalized_dict
这是否意味着,虽然我将 producers
的值指定为 Producer
或 List[Producer]
类型,但 if isinstance(producers[key], list):
不会导致 producers[key]
总是类型列表?我不明白,第一个版本的功能有什么问题。
这是 mypy
中已知的 issue,它不会像 dict_var[key]
那样缩小索引表达式的类型。作为解决方法,您可以为字典值使用显式变量:
from __future__ import annotations # needed for type annotations in > python 3.7
from typing import Dict, List, Union
class Producer(object):
pass
def normalize_producers(
producers: Dict[str, Union[Producer, List[Producer]]]
) -> Dict[str, List[Producer]]:
"""
Function to normalize producer input to have the same format
"""
normalized_dict: Dict[str, List[Producer]] = {}
for key, value in producers.items():
if isinstance(value, list):
normalized_dict[key] = value
else:
normalized_dict[key] = [value]
return normalized_dict