由于python是动态类型的,当然我们可以这样做:
def f(x):
return 2 if x else "s"
但是python的实际用途是什么?或换句话说,联盟类型是否存在于他们在球拍中的意义上?或者我们只是这样使用它们:
def f(x):
if x:
return "x"
我们需要的唯一“联盟”是否为?
答案 0 :(得分:15)
只有拥有静态类型语言时才需要进行联合键入,因为您需要声明对象可以返回多种类型之一(在您的情况下为int
或str
,或者在其他示例str
或NoneType
)。
Python仅处理对象,因此甚至不需要考虑“联合类型”。 Python函数返回它们返回的内容,如果程序员想要为不同的结果返回不同的类型,那么这就是他们的选择。那么选择是一个架构选择,并且对Python解释器没有任何影响(所以这里没有“基准”)。
Python 3.5确实引入了用于创建可选类型提示的标准,该标准包含Union[...]
和Optional[...]
注释。
答案 1 :(得分:9)
类型本身不存在,因为Python只是一种动态类型语言,但是,在较新的Python版本中,Union Type是Type Hinting的选项,
from typing import Union,TypeVar
T = TypeVar('T')
def f(x: T) -> Union[str, None]:
if x:
return "x"
您可以使用它来注释您的代码,从而启用IDE /编辑器级语法检查。
答案 2 :(得分:3)
以前的答案没有解决的一个用例是从预先存在的类型构建联合类型,并且让 isinstance()
认为预先存在的类型的任何实例都是联合类型。
Python 通过抽象基类支持这一点。例如:
>>> import abc
>>> class IntOrString(abc.ABC): pass
...
>>> IntOrString.register(int)
<class 'int'>
>>> IntOrString.register(str)
<class 'str'>
现在可以将 int
和 str
视为 IntOrString
的子类:
>>> issubclass(int, IntOrString)
True
>>> isinstance(42, IntOrString)
True
>>> isinstance("answer", IntOrString)
True
答案 3 :(得分:2)
添加到@MartijnPieters回答:
但实际上是否打算使用python的方式?
根据参数返回不同的类型从来都不是任何语言的好习惯。这使得测试,维护和扩展代码变得非常困难,而且恕我直言是一种反模式(但当然有时是必要的邪恶)。结果至少应该通过共同的界面来解决。
引入C union
的唯一原因是性能提升。但是在Python中,由于语言的动态性,你没有这种性能提升(正如Martijn注意到的那样)。实际上引入union
会降低性能,因为union
的大小始终是最大成员的大小。因此,Python永远不会像C一样union
。
答案 4 :(得分:2)
在需要使用Python tagged union/sum type的用例时,有两种选择:
枚举+元组
from enum import Enum
Token = Enum('Token', ['Number', 'Operator', 'Identifier', 'Space', 'Expression'])
(Token.Number, 42) # int type
(Token.Operator, '+') # str type 1
(Token.Identifier, 'foo') # str type 2
(Token.Space, ) # no data
(Token.Expression, 'lambda', 'x', 'x+x') # multiple data
isinstance
if isinstance(token, int):
# Number type
if isinstance(token, str):
# Identifier type
sumtypes模块
这些方法当然都有其各种缺点。
答案 5 :(得分:0)
从 Python 3.10 开始,您可以对联合类型使用 |
分隔符。以 What's New In Python 3.10 中的例子为例:
def square(number: int | float) -> int | float:
return number ** 2
# Instead of
def square(number: Union[int, float]) -> Union[int, float]:
return number ** 2
此外,如果您使用的是 Python 3.7+,则可以通过使用 __future__
包来拥有该功能,但有一些限制:
from __future__ import annotations
# Works in Python 3.7+
def square(number: int | float) -> int | float:
return number ** 2
# Works only in Python 3.10+
isinstance(3.10, int | float)
numeric = int | float
有关详细信息,请参阅 Union Types documentation 和 PEP 604。