Python中构建类TypeScript interface的自定义数据类型及调用优化问题
如何在Python中实现类似TypeScript Interface的自定义数据类型并简化调用
一、实现带约束的自定义数据类型
用dataclass定义符合需求的类,确保初始化时必须传入a或b中的一个,同时可添加禁止重复传入的约束:
from dataclasses import dataclass from typing import Optional, Union, overload @dataclass class Interface: a: Optional[str] = None b: Optional[int] = None def __post_init__(self): # 核心约束:必须传入a或b中的一个 if self.a is None and self.b is None: raise ValueError('必须传入a或b中的一个') # 可选约束:禁止同时传入a和b(按需调整) if self.a is not None and self.b is not None: raise ValueError('不能同时传入a和b')
二、让函数支持直接传入原始参数
要实现func('abc')或func(2)这类简化调用,同时保留类型检查能力,可通过函数重载+自动类型转换实现:
方法1:函数内直接处理转换
@overload def func(i: Interface) -> Interface: ... @overload def func(i: str) -> Interface: ... @overload def func(i: int) -> Interface: ... def func(i: Union[Interface, str, int]) -> Interface: if isinstance(i, Interface): return i elif isinstance(i, str): return Interface(a=i) elif isinstance(i, int): return Interface(b=i) else: raise TypeError('参数类型无效,仅支持Interface、str或int类型')
方法2:类方法封装转换逻辑(复用性更强)
如果多个函数需要复用转换逻辑,给Interface添加类方法封装转换规则:
@dataclass class Interface: a: Optional[str] = None b: Optional[int] = None def __post_init__(self): if self.a is None and self.b is None: raise ValueError('必须传入a或b中的一个') if self.a is not None and self.b is not None: raise ValueError('不能同时传入a和b') @classmethod def from_raw(cls, value: Union[str, int]) -> 'Interface': """将str/int原始值转换为Interface实例""" if isinstance(value, str): return cls(a=value) elif isinstance(value, int): return cls(b=value) else: raise TypeError('仅支持str或int类型的原始值')
对应函数可简化为:
@overload def func(i: Interface) -> Interface: ... @overload def func(i: str) -> Interface: ... @overload def func(i: int) -> Interface: ... def func(i: Union[Interface, str, int]) -> Interface: if isinstance(i, Interface): return i return Interface.from_raw(i)
三、效果验证
- 合法调用:
func('abc') # 返回 Interface(a='abc', b=None) func(2) # 返回 Interface(a=None, b=2) func(Interface(b=10)) # 直接传入实例也正常运行 - 非法调用:
func([1, 2]) # 运行时抛出TypeError,mypy等类型检查工具会提前提示类型错误 func(Interface()) # 初始化时抛出ValueError,符合约束要求
内容的提问来源于stack exchange,提问作者besi
相关产品推荐
相关产品推荐

