您可以在元组或列表中混合使用类型。为什么不能在类型提示中指定?
>>> from typing import Tuple, List
>>> t = ('a', 1)
>>> l = ['a', 1]
>>> t2: Tuple[str, int] = ('a', 1)
>>> l2: List[str, int] = ['a', 1]
TypeError: Too many parameters for typing.List; actual 2, expected 1
您可以在元组或列表中混合使用类型。为什么不能在类型提示中指定?
>>> from typing import Tuple, List
>>> t = ('a', 1)
>>> l = ['a', 1]
>>> t2: Tuple[str, int] = ('a', 1)
>>> l2: List[str, int] = ['a', 1]
TypeError: Too many parameters for typing.List; actual 2, expected 1
List
只接受一个类型,并且该列表中的每个元素都必须具有该类型。但是,类型理论还提供了和类型,可以将其视为围绕从某个固定类型集合中选择的一个值的包装器。和类型由 typing.Union
支持。要指定列表是 int
和 str
值的混合,请使用:List[Union[str, int]]
作为类型提示。
相比之下,元组是“乘积类型”的一个例子,即由一组固定类型组成的类型,并且其值是从乘积类型中每个类型中选择的值的集合。 Tuple[int,int,int]
、Tuple[str,int]
和 Tuple[int,str]
都是不同的类型,它们通过产品中类型的数量和它们出现的顺序来区分。
虽然你可以使用 Union
,但是一般来说,如果能够避免,列表应该是同质的而不是异质的:
from typing import List, Union
lst: List[Union[str, int]] = [1, 'a']
myp
至少可以很好地接受这个。
这意味着你的列表访问器将返回一个联合类型,通常需要在任何下游函数中处理不同可能的类型。接受联合类型通常不会有太大问题。
针对现在的读者:如果你正在使用 Python 3.10 及以上版本,类型支持已经有了很大的变化。Union
可以用 |
缩写,并且对于大多数常见类,你不再需要导入 typing
。因此:
from typing import List, Union
my_list : List[Union[str, float]] = ["example", 0, 1, 2]
等同于:
my_list : list[str | float] = ["example", 0, 1, 2]
您可以在PEP 604, PEP 612, PEP 613和PEP 647中找到每个细节。
然而,如果您想指定列表中每个元素的类型,例如从函数返回值时,应该使用类型tuple
而不是list
。在这种情况下,您应该使用逗号而不是|
:
def my_list(text : str, number : float) -> tuple[str, float] :
return text, number
默认情况下(无论类型),此函数返回一个元组。如果您绝对需要一个列表,请执行以下操作:
def my_list(text : str, number : float) -> tuple[str, float] :
return [text, number]
使用List
和Union
的方法在某些情况下是可行的,但容易导致错误并不是最佳实践。这就是为什么List
不允许多种类型的原因。让我解释一下。
做这件事的错误方式(就像其他答案所写的那样)是这样的。
from typing import Union, List
List[Union[str, int]]
有两个问题。
虽然它可能在短期内解决问题,但这不是在Python中使用类型提示的正确方式。
这是您使用列表的地方。列表是可变的,因此如果您添加了类型,并更改了列表,则类型不再准确。因此,您永远不应该为不同类型使用List
。
from typing import List
my_list = List[str]
如果您确实需要对列表进行类型提示,请使用Tuple
。元组是不可变的,因此您可以确保元组内部具有正确的类型。
from typing import Tuple
my_list = Tuple[str, int, int, str, int]
Tuple
是一个特殊情况。 - jonrsharpe