泛型js typescript泛型详解
论文探讨了Python泛型类中实现TypeVar默认值或任选TypeVar的挑战与解决方案。由于Python语言目前不直接支持在泛型类中为TypeVar设定值默认,文章提出了一种通过创建特化(如“简化”)泛型类来简化常见的策略。同时,文章也展望了PEP 696等提议可能会带来未来的原生支持,为开发者提供了当前可移植的实践方法和对语言演进的理解。泛型类中 TypeVar 默认值的需求背景
在 python 中,泛型(generics)通过 typevar 和 generic 提供强大的类型抽象能力,使得代码在保持灵活的同时,也能够获得静态检查类型的优势。然而,在某些情况下,可能希望泛型参数具有默认值,或者能够根据其他 typevar的值自动推断。
考虑一个表示装饰器接口的协议:fromtyping import Protocol, TypeVar, Generic, CallableTIn = TypeVar('TIn', contravariant=True)TOut = TypeVar('TOut', covariant=True)class Decorator(Protocol, Generic[TIn, TOut]): quot;quot;quot;表示一个装饰的值,用于简化类型定义。 quot;quot;quot; def __call__(self, value: TIn) -gt; TOut: ...# 示例:一个接收和返回相同类型的装饰器 IntFunction = Callable[[int, int], int]def register_operator(op: str) -gt; 装饰器[IntFunction, IntFunction]: def inner(value: IntFunction) -gt; IntFunction: # 执行注册或其他逻辑返回值 return inside@register_operator(quot; quot;)def add(a: int, b: int) -gt; int: return a b登录后复制
在这个例子中,Decorator[TIn,TOut]定义了一个接受TIn 类型并 TOut 类型的可调用对象。在许多常见的装饰器场景中,被装饰函数的输入类型 TIn 和输出类型 TOut 是相同的。此时,我们希望能够简化类型注解,例如将 Decorator[IntFunction, IntFunction] 简化为 Decorator[IntFunction],并假设取消的 TOut 默认为 TIn。
理想的语法可能类似:#这种语法目前不被Python支持class Decorator(Protocol, Generic[TIn, TOut = TIn]): def __call__(self, value: TIn) -gt; TOut: ... 登录后复制
不过,Python 目前的类型系统并不直接支持在 Generic 定义中为 TypeVar 设置默认值。当类型泛参数未完全指定时,它们通常会被视为 Any 或未知,无法实现我们期望的类型推断。
立即学习“Python免费学习笔记(深入)”;现有的解决方案:创建特化泛型类
针对Python语言当前的限制,一种有效的解决方案是创建特化的泛型类。对于TIn和TOut相同的情况,我们可以定义一个“直观”的Decorator子类,它底层提供了这两个类型变量。from type import Protocol,TypeVar,Generic,CallableTIn = TypeVar('TIn', contravariant=True)TOut = TypeVar('TOut', covariant=True)TSym = TypeVar('TSym') # 用于泛泛型的 TypeVarclass Decorator(Protocol, Generic[TIn, TOut]): quot;quot;quot; 表示一个被装饰的值,用于简化定义类型。 quot;quot;quot; def __call__(self, value: TIn) -gt; TOut: ...class SymmetricDecorator(Decorator[TSym, TSym], Generic[TSym], Protocol): quot;quot;quot;表示一个输入和输出类型相同的装饰器。简化了当 TIn 和 TOut 时的类型注解。 quot;quot;quot;通过登录后复制
在此实现中: Copilot
Copilot是由微软公司开发的一款AI生产力工具,旨在通过先进的人工智能技术,帮助用户快速完成各种任务,提升工作效率。63查看详情装饰器保留其原始定义,用于处理输入和输出类型可能不同的情况。TSym是一个新的TypeVar,专门用于表示当前情况下的单一类型。
SymmetricDecorator 继承自 Decorator[TSym, TSym],声明本身也是一个泛型类 Generic[TSym]。通过这种方式,SymmetricDecorator 强制其 TIn 和 TOut 参数都为 TSym,从而实现了类型统一。
现在,我们使用 SymmetricDecorator 来简化之前的 register_operator 函数的注类型解:# 示例使用:SymmetricDecorator简化类型注解 IntFunction = Callable[[int, int], int]def register_operator_symmetry(op: str) -gt; SymmetricDecorator[IntFunction]: # 简化端点 ^ def inner(value: IntFunction) -gt; IntFunction: # 执行注册或其他逻辑返回值 return inside@register_operator_symmetry(quot; quot;)def add_symmetry(a: int, b: int) -gt; int:返回一个登录后复制
通过引入 SymmetricDecorator,当装饰器不改变被装饰函数的类型签名时,类型注解更加简洁明了,同时Mypy等静态类型检查工具仍然能够正确验证类型。优点与考量优点:简洁性:对于最常见的“简洁”场景,类型注解显着简化。类型安全:保留了Mypy等工具提供了静态类型检查的明确性。明确的:SymmetricDecorator的命名清楚地表达了其输入和输出类型一致的特性。考量:额外类:需要定义一个额外的类,可能会增加大量的代码量。命名:需要为特化类选择一个近似的名称,如 SymmetricDecorator 或 IdentityDecorator。未来展望:PEP 696 与 TypeVar 默认值
表示的是,Python 社区已经意识到在泛型中为 TypeVar 提供默认值的需求。PEP 696提案(“TypeVarDefaults”)正致力于引入这个功能。
如果该提议被采纳并实现,未来的 Python 版本将可能支持类似以下的衍生语法:# PEP 696 提议的未来语法 (当前不工作)from Typing import Protocol, TypeVar, Generic, TypeVarTuple# 假设 TypeVar 支持默认值 TIn = TypeVar('TIn', contravariant=True)TOut = TypeVar('TOut', covariant=True, default=TIn) # 假设的默认参数类Decorator(Protocol, Generic[TIn, TOut]): def __call__(self, value: TIn) -gt; TOut: ...登录后复制
一旦 PEP 696 被实现,开发者将能够直接在 TypeVar 定义中指定默认值,从而避免创建额外的特化类,使泛型定义更加灵活和强大。这将是 Python类型系统的一个重要进步,进一步提升其表达能力和可用性。总结
尽管Python目前在泛型类中不直接支持TypeVar 设置默认值,但通过创建特化的泛型类型(如 SymmetricDecorator)可以有效地解决常见问题的简化需求,同时保持类型安全。这种方法是当前处理此类问题的最佳实践。展望未来,随着 PEP 696 等提议的推进,Python 的类型系统有望重新支持 TypeVar默认值,强迫将提供更简洁、更强大的泛型定义方式。开发者应这些特性语言的发展,以便在适当的时机采用最新的、更优雅的关注方案。
以上就是Python泛型类中TypeVar默认值的实现策略与未来展望详细的内容,更多请关注乐哥常识网其他相关文章!