如何在Python中为类字典键值结构对象添加类型注解?
如何为第三方自定义类标注类似字典的泛型类型?
假设我们有一个第三方提供的类A,代码如下:
from typing import Any class A: def __init__(self, *args): self.items: list[int] = list(args) def __getitem__(self, k: str): v = int(k) if v in self.items: return v return None def __setitem__(self, k: str, _: Any = None): v = int(k) print(f'Value {_} is not important') if v not in self.items: self.items.append(int(k))
这个类支持通过object[element_name]的语法访问元素,行为类似字典但有特殊逻辑:
a = A(1, 2, 3) a['4'] = 'Something' print(a['2']) # 输出: 2 print(a['4']) # 输出: 4
对于普通字典,我们可以用dict[str, int]来标注键为str、值为int的类型,但直接用A[str, int]是无效的——因为A本身不是泛型类。现在需要在不修改原类A的前提下,创建一个继承自A的子类B,要求B和A行为完全一致,仅支持泛型类型注解。
解决方案:让子类成为泛型类并补充类型注解
我们可以通过让子类继承Generic类,同时重写__getitem__和__setitem__方法(仅补充类型注解,方法体调用父类实现以保留原行为),来实现泛型类型标注:
from typing import Generic, TypeVar, Optional, Any # 定义类型变量,限定键的类型为str,值的类型为int Key = TypeVar('Key', bound=str) Value = TypeVar('Value', bound=int) class B(A, Generic[Key, Value]): def __getitem__(self, k: Key) -> Optional[Value]: # 直接调用父类方法,保证行为一致 return super().__getitem__(k) def __setitem__(self, k: Key, _: Any = None) -> None: # 直接调用父类方法,保证行为一致 super().__setitem__(k, _)
使用示例
现在就可以用B[str, int]来标注类型,类型检查器会正确识别键和值的类型:
# 标注变量b为键是str、值是int的B类型实例 b: B[str, int] = B(1, 2, 3) b['4'] = '任意值' # 类型检查器会识别b['2']的类型为Optional[int]
这个方案的核心是通过泛型子类来“包装”原类的行为,同时为索引操作补充类型信息,完全保留原类的功能,只增加类型注解支持。
内容的提问来源于stack exchange,提问作者rzlvmp
相关产品推荐
相关产品推荐

