mypy场景下列表转numpy数组的合法类型标注方案求解
Numpy数组转换场景下的Mypy类型兼容解决方案
下面是几种符合类型规范、不需要标注Any或加type: ignore的解决方案:
方案1:用函数封装隔离不同类型的生命周期
把列表构建的逻辑封装在独立函数中,函数直接返回转换好的numpy数组,临时列表会在函数执行结束后自动被垃圾回收,无需手动处理:
import numpy as np from typing import List def build_array() -> np.ndarray: tmp_list: List[int] = [] for j in range(10): # 复杂操作逻辑写在这里 tmp_list.append(j) return np.asarray(tmp_list) a: np.ndarray = build_array()
方案2:分阶段操作字典类型
对于字典存储的场景,把列表操作和数组转换拆成两个独立步骤,mypy支持同作用域下变量重标注来识别类型变更:
import numpy as np from typing import Dict, List # 第一阶段:全量完成列表的修改操作 a: Dict[str, List[int]] = {'0': [0, 1, 2], '1': [0, 1, 2]} for v in a.values(): v.append(3) # 第二阶段:统一转换为数组类型,重标注变量类型 a: Dict[str, np.ndarray] = {k: np.asarray(v) for k, v in a.items()}
方案3:用cast做窄化处理适配单循环操作
如果必须在同一个循环里完成列表修改和数组赋值,可以通过cast先把Union类型窄化为列表,保证append操作合法:
import numpy as np from typing import Dict, List, Union, cast a: Dict[str, Union[List[int], np.ndarray]] = {'0': [0, 1, 2], '1': [0, 1, 2]} for k, v in a.items(): # 窄化当前值为列表类型,适配append操作 current_list = cast(List[int], v) current_list.append(3) a[k] = np.asarray(current_list)
补充说明
你之前担心的临时变量垃圾回收问题是不必要的:Python的引用计数机制会自动回收没有被任何变量引用的内存,如果你使用b = np.asarray(a)之后没有其他地方引用a,a占用的内存会被自动释放,无需手动执行del a。
内容的提问来源于stack exchange,提问作者Ignacio
相关产品推荐
相关产品推荐

