如何为可接受整数或descriptor的方法参数添加类型提示?
为NamedTuple属性(Descriptor)添加类型提示的方案
要给NamedTupleList类中attempt_access方法的column参数添加支持int和NamedTuple属性(descriptor)的类型提示,可按以下方式实现:
1. 定义Descriptor协议
NamedTuple的属性本质是实现了descriptor协议的_tuplegetter对象,我们可以通过typing.Protocol描述这个接口,让类型检查器识别符合条件的descriptor:
from typing import Protocol, Any, NamedTuple, Union class Descriptor(Protocol): def __get__(self, instance: Any, owner: type | None = None) -> Any: ...
2. 更新方法类型提示
将column参数的类型设为Union[int, Descriptor],同时给__init__方法补充类型提示,让代码更严谨:
class Record(NamedTuple): id: int name: str age: int class NamedTupleList: def __init__(self, data: list[Record]) -> None: self._data = data def attempt_access(self, row: int, column: Union[int, Descriptor]) -> Any: r = self._data[row] try: val = r[column] except TypeError: val = column.__get__(r) return val
3. 泛型适配(可选)
如果需要适配任意NamedTuple而非仅Record,可以结合TypeVar和Generic实现泛型版本:
from typing import Protocol, Any, NamedTuple, Union, TypeVar, Generic T = TypeVar('T', bound=NamedTuple) class Descriptor(Protocol): def __get__(self, instance: T, owner: type[T] | None = None) -> Any: ... class NamedTupleList(Generic[T]): def __init__(self, data: list[T]) -> None: self._data = data def attempt_access(self, row: int, column: Union[int, Descriptor]) -> Any: r = self._data[row] try: val = r[column] except TypeError: val = column.__get__(r) return val
替代方案(不推荐)
也可以直接引用Python内部私有类型collections._tuplegetter,但该类型属于内部实现,可能随Python版本变化,因此更推荐使用Protocol的方式。
内容的提问来源于stack exchange,提问作者MikeP
相关产品推荐
相关产品推荐

