如何通过装饰器扩展类并支持Intellisense智能提示
解决方案
针对你的需求,这里提供两种可行的实现方案,分别适用于可子类化和不可子类化的原类场景:
方案一:子类化原类(推荐,适用于多数场景)
如果原类允许子类化(如自定义类USCode或内置类型str),直接通过子类继承原类并添加SupportsInt特性,既能保留原类的所有成员以支持智能提示,又无需修改原类本身。
示例1:自定义原类USCode
from typing import SupportsInt # 原类(不可修改) class USCode: NEWYORK = 17 CALIFORNIA = 18 def __str__(self): return '5' # 子类继承原类并添加SupportsInt能力 class USCodeInt(USCode, SupportsInt): def __int__(self) -> int: return 5 # 定义AreaCode命名空间 class AreaCode: US = USCodeInt() # 测试验证 print(AreaCode.US) # 输出: '5' print(AreaCode.US.NEWYORK) # 输出: 17 print(int(AreaCode.US)) # 输出: 5
示例2:内置类型str
from typing import SupportsInt # 子类化str并添加属性和SupportsInt能力 class USAreaCode(str, SupportsInt): NEWYORK = 17 CALIFORNIA = 18 def __int__(self) -> int: return int(self) # 定义AreaCode命名空间 class AreaCode: US = USAreaCode('5') # 测试验证 print(AreaCode.US) # 输出: '5' print(AreaCode.US.NEWYORK) # 输出: 17 print(int(AreaCode.US)) # 输出: 5
优势:
- VSCode Pylance可直接识别原类的所有成员,智能提示完整
- 类型检查工具会认可
int(AreaCode.US)的调用,无报错 - 实现简单,无需复杂的包装逻辑
方案二:通用包装器(适用于无法子类化的原类)
如果原类无法子类化(如某些受限的第三方类),可通过**协议(Protocol)**定义原类的成员结构,搭配泛型包装器实现需求,同时保留智能提示和类型检查支持。
from typing import Generic, TypeVar, SupportsInt, Protocol # 定义协议,镜像原类的成员结构 class USCodeProtocol(Protocol): NEWYORK: int CALIFORNIA: int T = TypeVar('T', bound=USCodeProtocol) # 泛型包装器类 class CodeWrapper(Generic[T], SupportsInt): def __init__(self, wrapped: T, int_val: int): self._wrapped = wrapped self._int_val = int_val def __int__(self) -> int: return self._int_val def __str__(self) -> str: return str(self._wrapped) # 委托属性访问给原实例 def __getattr__(self, name: str): return getattr(self._wrapped, name) # 原类(不可修改且无法子类化) class USCode: NEWYORK = 17 CALIFORNIA = 18 def __str__(self): return '5' # 定义AreaCode命名空间 class AreaCode: US: CodeWrapper[USCode] = CodeWrapper(USCode(), 5) # 测试验证 print(AreaCode.US) # 输出: '5' print(AreaCode.US.NEWYORK) # 输出: 17 print(int(AreaCode.US)) # 输出: 5
优势:
- 无需修改或子类化原类
- 通过协议定义成员结构,Pylance可提供完整的智能提示
- 类型检查工具会认可
int()调用,无报错
内容的提问来源于stack exchange,提问作者Simelvia
相关产品推荐
相关产品推荐

