python中的泛型使用TypeVar

1.引入为什么需要TypeVar

PEP484的作者希望借助typing模块引入类型提示,不改动语言的其它部分。通过精巧的元编程技术,让类支持[]运算不成问题。但是方括号内的T变量必须在某处定义,否则要大范围改动python解释器才能让泛型支持特殊的[]表示法。

鉴于此,我们增加了typing.TypeVar构造函数,把变量名称引入当前命名空间。

由于java,c#和TypingScript等语言不要求实现声明类型变量的名称,因此没有与python的TypeVar类对应的结构。

2.示例

from collections.abc import Iterable
from typing import TypeVar

T = TypeVar('T')


def mode(data: Iterable[T]) -> T:
    return data[1:]


if __name__ == '__main__':
    list1 = [1.1,1.2,1.3,1.4,1.5]
    list2 = [1,2,3,4,5]
    data1 = mode(list1)
    data2 = mode(list2)
    print(data1)
    print(data2)

3.受限的TypeVar

TypeVar还接受一些位置参数,以对类型参数施加限制。

from collections.abc import Iterable
from decimal import Decimal
from fractions import Fraction
from typing import TypeVar

NumberT = TypeVar('NumberT', float, Decimal, Fraction)
def mode(data: Iterable[NumberT]) -> NumberT:
  ...

4.有界的TypeVar

from collections.abc import Iterable, Hashable
def mode(data: Iterable[Hashable]) -> Hashable:

现在的问题是,返回的项是Hashable类型。Hashable是一个抽象基类。只实现了__hash__方法。因此,除了调用hash(),类型检查工具不会允许对返回值做其它任何操作。

所以,这么做没有任何意义。解决方法是使用TypeVar的另一个可选参数,即关键字参数bound。这个参数会为可接受的类型设定一个上边界。

下面的实例使用bound=Hashable指明,类型参数可以是Hashable或它的任何子类型。

from collections  import Counter
from collections.abc import Iterable, Hashable
from typing import TypeVar
#Python学习交流群:711312441
HashableT = TypeVar('HashableT', bound=Hashable)
def mode(data: Iterable[HashableT]) -> HashableT:
  pairs = Counter(data).most_common(1)
  if len(pairs) == 0:
    raise ValueError('no mode for empty data')
  return pairs[0][0]
<think>嗯,用户想了解Python的概念和用法。首先,我需要回忆一下Python支持。记得Python本身是动态类语言,但通过typing模块提供了类提示和的功能。允许代码处理多种类,提高重用性和类安全。 首先,我应该解释是什么,为什么有用。然后介绍Python中实现的方式,比如TypeVar和Generic。可能需要提到typing模块中的相关类,比如Generic和TypeVar,以及如何定义类和函数。 用户可能需要示例,所以得准备代码例子。比如类的定义,使用TypeVar声明类变量,继承Generic来创建类。还要注意说明在Python主要在类检查时起作用,运行时可能不会强制类,这可能需要提到mypy这样的静态类检查工具。 然后,用户可能想知道实际应用场景,比如容器类、数据处理的函数等。可能需要举一个栈的例子,或者处理不同数据类的函数。 另外,用户的问题中引用了四个参考资料,我需要确保引用正确。比如引用[1]提到Python没有直接支持,但可以通过技巧实现;引用[2]和[4]详细说明了TypeVar和Generic的使用;引用[3]可能涉及获取的方法,但用户的问题可能不需要深入这个方面,不过可能需要简要提及。 还需要注意用户提到的格式要求,比如行内数学公式用$...$,独立公式用$$...$$,但在这个问题中可能用不上数学公式,不过要确保代码块正确使用Python语法。同时生成相关问题,可能需要包括的优点、定义方法、与静态语言的区别、应用场景等。 可能存在的误区是用户认为Python像Java或C#那样在运行时实例化,需要澄清Python主要用于静态类检查,而不是运行时类强制。此外,可能需要说明Python 3.5+版本对typing模块的支持情况,以及如何使用mypy进行类检查。 最后,检查回答结构是否清晰,分点解释概念、实现方式、示例和注意事项,并确保引用正确标注在相关段落后。</think>### Python的概念及用法详解 #### 一、的基本概念 是一种编程范式,允许在定义函数、类或数据结构时使用**类参数**,这些参数在使用时可以被替换为具体类(如$int$、$str$或自定义类)。的主要优势包括: - **代码重用**:同一逻辑可处理多种数据类[^4]; - **类安全**:静态类检查工具(如`mypy`)能提前发现类错误; - **可读性**:明确的类注解增强代码可维护性。 #### 二、Python的实现方式 Python通过`typing`模块提供支持,核心工具包括: 1. **`TypeVar`**:定义变量 示例:声明一个变量$T$: ```python from typing import TypeVar, Generic T = TypeVar('T') # 定义变量T ``` 2. **`Generic`基类**:构建类 继承`Generic`并指定类变量,定义类: ```python class Stack(Generic[T]): def __init__(self): self.items: list[T] = [] def push(self, item: T) -> None: self.items.append(item) def pop(self) -> T: return self.items.pop() ``` 此时$Stack[int]$表示一个整数栈,$Stack[str]$表示字符串栈[^2]。 #### 三、具体示例 1. **函数** 实现一个交换两个变量的函数: ```python from typing import TypeVar T = TypeVar('T') def swap(a: T, b: T) -> tuple[T, T]: return b, a ``` 此函数可处理任意相同类的参数,如$swap(1, 2)$或$swap("x", "y")$[^2]。 2. **多类** 使用多个类变量: ```python K = TypeVar('K') V = TypeVar('V') class Pair(Generic[K, V]): def __init__(self, key: K, value: V): self.key = key self.value = value ``` 可实例化为$Pair[int, str](1, "one")$。 #### 四、注意事项 - **静态类检查**:Python依赖类检查工具(如`mypy`),运行时不会强制类约束; - **限制类范围**:可通过`bound`参数约束类变量,例如`T = TypeVar('T', bound=int)`限定$T$为$int$或其子类; - **容器类典应用**:特别适合实现列表、字典等容器,增强类表达能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值