Python3.9+mypy0.910环境下csv.DictWriter类型注解报错如何解决
修复方案
完整可通过mypy检查的代码
from typing import List, Dict, Union from io import BytesIO, TextIOWrapper from csv import DictWriter, QUOTE_ALL def csv_bytes_from_dict_list(dict_list: List[Dict[str, Union[str, int]]]) -> bytes: # 提前处理空列表边界,避免运行时索引错误,也满足mypy类型校验要求 if not dict_list: return b"" with TextIOWrapper(BytesIO(), encoding="utf-8") as r: # 显式标注DictWriter泛型参数为字段名类型str,fieldnames显式转list适配类型要求 w: DictWriter[str] = DictWriter( r, fieldnames=list(dict_list[0].keys()), quotechar='"', quoting=QUOTE_ALL ) w.writeheader() w.writerows(dict_list) r.flush() r.buffer.seek(0) b = r.buffer.read() return b
错误原因与修复说明
- 关于
Missing type parameters for generic type "DictWriter"报错:
DictWriter是泛型类,唯一的泛型参数是字段名的类型,而非传入的字典整体类型,之前误将整个字典结构作为泛型参数传入,导致后续writerows参数类型匹配错误,标注为DictWriter[str]即可匹配字段名都是字符串的场景。 - 关于fieldnames参数类型不兼容报错:
DictWriter要求fieldnames参数为Sequence类型,而dict.keys()返回的是KeysView类型,需显式转为list。之前写list(dict_list[0])触发报错是因为mypy 0.910对直接遍历字典的类型推断有兼容性问题,显式调用.keys()再转list即可解决。 - 额外补充的空列表判断是为了避免运行时传入空的dict_list触发索引越界错误,同时也能让mypy确认
dict_list[0]一定存在,不会额外抛出非空校验报错。
内容的提问来源于stack exchange,提问作者The Fool
相关产品推荐
相关产品推荐

