在Python中,泛型是一种编程概念,它允许在编写函数、类或数据结构时使用参数化类型,以提高代码的灵活性和复用性。
通过
泛型
,我们可以编写更通用的代码
,使其能够适用于多种不同类型的数据。
Python 中的泛型是使用
typing
模块中的
TypeVar
和
Generic
进行实现的。
TypeVar
用于定义泛型类型变量,而
Generic
用于定义泛型类或函数。
typing
模块中的泛型
支持包括一系列的泛型类型和类型变量,例如
List
、
Dict
、
Tuple
等。开发者可以使用这些泛型类型来声明具有泛型参数的数据结构或函数签名。此外,Python 3.9 引入了更多强大的泛型支持,包括
Literal
、
TypedDict
等新的泛型类型。
需要注意的是,Python 中的泛型
类型提示
仅用于静态类型检查和文档说明,并不影响运行时的行为。Python 解释器不会强制执行类型提示,因此在运行时仍然可以传入任何类型的参数。
下面是一些关于Python泛型的详细解释:
1. 泛型类型变量(Generic Type Variables):
在使用泛型时,我们通常会定义一个泛型类型变量,用于表示某种不确定的类型。泛型类型变量通常使用大写字母命名,比如
T
、
U
、
V
等。
T = TypeVar('T')
2. 泛型函数(Generic Functions):
泛型函数是可以接受一个或多个泛型类型参数的函数。这些参数可以用来指定函数参数的类型、返回值的类型或函数内部使用的其他类型。
from typing import TypeVar, List
T = TypeVar('T')
def first_element(items: List[T]) -> T:
return items[0]
int_list = [1, 2, 3, 4, 5]
print(first_element(int_list)) # 输出: 1
str_list = ["Hello", "World", "Python"]
print(first_element(str_list)) # 输出: Hello
在这个例子中,我们创建了一个整数列表 int_list
和一个字符串列表 str_list
。我们使用 first_element
函数获取了这两个列表的第一个元素,分别是整数 1
和字符串 "Hello"
。
from typing import TypeVar, List
# 定义一个泛型类型T
T = TypeVar('T')
def reverse_list(items: List[T]) -> List[T]:
"""反转列表"""
return items[::-1]
# 使用泛型函数
int_list = [1, 2, 3, 4, 5]
str_list = ["apple", "banana", "orange"]
reversed_ints = reverse_list(int_list)
reversed_strs = reverse_list(str_list)
print(reversed_ints) # 输出: [5, 4, 3, 2, 1]
print(reversed_strs) # 输出: ['orange', 'banana', 'apple']
3. 泛型类(Generic Classes):
泛型类是可以接受一个或多个泛型类型参数的类。这些参数可以用来指定类的属性类型、方法参数类型、方法返回值类型或类内部使用的其他类型。
from typing import TypeVar, Generic
T = TypeVar('T')
class Box(Generic[T]):
def __init__(self, item: T):
self.item = item
def get_item(self) -> T:
return self.item
int_box = Box[int](10)
print(int_box.get_item()) # 输出: 10
str_box = Box[str]("Hello")
print(str_box.get_item()) # 输出: Hello
在这个例子中,我们创建了一个整数 Box
实例 int_box
,存储了整数 10
,并使用 get_item
方法获取了该整数。我们还创建了一个字符串 Box
实例 str_box
,存储了字符串 "Hello"
,并使用 get_item
方法获取了该字符串。
4. 泛型约束(Generic Constraints):
有时,我们希望泛型类型只能是特定的类型或其子类。在这种情况下,我们可以使用泛型约束来限制泛型类型的范围。
from typing import TypeVar, List, Union
T = TypeVar('T', int, float)
def sum_values(items: List[T]) -> Union[int, float]:
return sum(items)
int_list = [1, 2, 3, 4, 5]
print(sum_values(int_list)) # 输出: 15
float_list = [1.5, 2.5, 3.5, 4.5, 5.5]
print(sum_values(float_list)) # 输出: 16.0
在这个例子中,我们创建了一个整数列表 int_list
和一个浮点数列表 float_list
。我们使用 sum_values
函数计算了这两个列表的总和,分别是整数 15
和浮点数 16.0
。
代码片段中,-> Union[int, float]
是函数 sum_values
的返回类型注解。它表示函数的返回值可以是整数(int
)或浮点数(float
)类型之一。这是通过 typing
模块中的 Union
类型帮助器实现的。
需要注意的是,Python 中的泛型类型提示仅用于静态类型检查和文档说明,并不影响运行时的行为。Python 解释器不会强制执行类型提示,因此在运行时仍然可以传入任何类型的参数。
类型注解是指在代码中为变量、函数参数和返回值等添加类型信息的过程。它们使用 Python 的 typing
模块提供的类型帮助器,如 List
、Union
、TypeVar
等,来描述变量或函数参数的类型。类型注解的主要目的是提高代码的可读性、可维护性,并为静态类型检查工具提供有关代码结构的信息。
5. 使用泛型时的注意事项:
- 泛型只是一种约定和规范,Python解释器不会强制执行泛型类型。
- 泛型可以提高代码的可读性和可维护性,但也可能增加代码的复杂度。
- 在使用泛型时,应该遵循Python的命名规范,使代码易于理解和维护。
- 当使用第三方库中的泛型类型时,应该查阅文档以了解其使用方法和约束条件。
总之,泛型是一种强大的编程工具,可以帮助开发者编写更通用、更灵活的代码,但在使用时需要注意理解其原理和限制。
---------
from typing import TypeVar, Generic
# 定义一个泛型类型T
T = TypeVar('T')
class Storage(Generic[T]):
def __init__(self, initial_value: T):
self._value = initial_value
def get_value(self) -> T:
"""获取存储的值"""
return self._value
def set_value(self, new_value: T) -> None:
"""设置新的值"""
self._value = new_value
# 使用泛型类
int_storage = Storage(10)
print(int_storage.get_value()) # 输出: 10
int_storage.set_value(20)
print(int_storage.get_value()) # 输出: 20
str_storage = Storage("Hello")
print(str_storage.get_value()) # 输出: Hello
str_storage.set_value("World")
print(str_storage.get_value()) # 输出: World
这段代码演示了如何使用泛型类(Generic Class)来创建可以存储不同类型数据的存储器。
typing 是在 python 3.5 才有的模块
Python 类型提示:https://www.cnblogs.com/poloyy/p/15145380.html
常用类型提示
https://www.cnblogs.com/poloyy/p/15150315.html
https://www.cnblogs.com/poloyy/p/15153883.html...
在写项目的时候,我实现了一个泛型容器,希望能够用来兼容多个实体的shema。但是这时候出问题了,我发现通过Generic容器传入的schema参数并没有什么用?
这是为什么呢?
原因就在于:泛型只是一个hint,可以帮助提示你应该输入什么类型的参数以及可以提示ID E此处应该传入什么参数,从而提醒你是否出错的参数。但是泛型(包括typing里的所有变量)并无法帮助你完成schema的功能。所以,.
在Python的类型提示(type hints)中,TypeVar是用于定义类型变量的工具。类型变量在泛型编程中非常有用,它们允许你定义灵活的函数、类或方法,这些函数、类或方法可以在多种类型上操作,而不仅仅是特定的类型。TypeVar 允许你定义一个变量,该变量可以代表任何类型或一组类型。然后,你可以使用这个类型变量来定义函数或类的参数和返回类型。
这里写目录标题类型提示了解标准库typing初见泛型小试泛型泛型示例完整代码
不知道从什么时候起,我写Python代码习惯给变量加上类型注解。这虽然降低了Python的灵活性,但确确实实在后续维护的过程中提供了很好的帮助。
第一次听到泛型这个词,是在Java中了解到的,但具体做什么,有什么作用,都是比较模糊的。因为我本身对Java只是了解并且也没有用Java做过什么实际项目,所以一直对泛型不太明白。
在官方文档中描述了泛型的使用方法,我将从小例子开始,看看泛型是如何帮助我们的。
当前有一个get函
Optional和Generic1.1 Optional用法及样例定义Optional是typing模块中的一个类型别名,用于表示一个值可以是某种类型,也可以是None。用法等价于,表示该值可以是类型X或None。# 返回值可以是字符串或 Noneelse:1.2 Generic用法定义Generic是typing模块中的一个基类,用于定义泛型类或泛型函数,使其能够处理多种数据类型。它允许你在类或函数中使用类型变量(TypeVar用法:通过继承Generic。
指定类型的时候用list、set、dict、tuple也是可以的,但是不能指定里面的元素类型。当你传入参数与设置的参数类型不一样时,只会warning,而不会报错。Tuple[T]指定一个类型的时候,仅针对同一个索引下的元素类型。如果想向List[T]一样指定全部的类型,可以Tuple[T,…Dict[T,T]第一个参数指定键的类型,第二个参数指定值得类型。Union[int,str]表示既可以是int,也可以是str。且List[T]、Set[T]只能传一个类型,传多个会报错。...
Python 的泛型(Generics)是类型提示的一个高级特性,用于指示某些数据结构或函数可以接受多种数据类型,例如使得一个函数的参数能够接收多种类型的数据或者使得一个类能够接收并存储不同种类的数据。泛型在 Python 中通常通过模块typing实现。泛型的使用有助于提高代码的可读性和健壮性,尤其是在大型项目和团队协作中。