具有多个任意但相同类型的元组
Tuple with multiple numbers of arbitrary but equal type
目前,我正在检查具有以下形式的多个(例如三个)任意但相同类型的元组:
from typing import Tuple, Union
Union[Tuple[int, int, int], Tuple[float, float, float]]
我想让这个检查更通用,也允许 numpy
数字类型。 IE。我尝试使用 numbers.Number
:
from numbers import Number
from typing import Tuple
Tuple[Number, Number, Number]
上面的片段也允许混合类型的元组,只要一切都是数字。
我想将元组限制为相同类型的数字。
如何实现?
从技术上讲,这个问题适用于 Python 和类型提示规范本身。然而,正如评论中指出的那样,它的处理是特定于实现的,即 MyPy 不会捕获每个边缘情况 and/or 不一致。就个人而言,我正在使用 运行 时间检查 typeguard 进行测试并在生产中完全停用它们。
您可以将 TypeVar
与 bound
参数一起使用。它允许将类型限制为给定类型的子类型。在您的情况下,类型应该是 Number
:
的子类型
from numbers import Number
from typing import TypeVar
T = TypeVar('T', bound=Number)
Tuple[T, T, T]
为什么有效?
TypeVar
是一个允许在类型签名中多次使用特定类型的变量。最简单的例子:
from typing import TypeVar, Tuple
T = TypeVar('T')
R = TypeVar('R')
def swap(x: T, y: R) -> Tuple[R, T]:
return y, x
静态类型检查器将推断函数 swap
的参数应该与输出的顺序相同(注意 return 类型 T 将与输入类型 T 相同) .
接下来,引入对 TypeVar
的限制可能会有用。例如,可以将类型变量的值限制为特定类型:TypeVar('T', int, str)
。在这个答案中,我们使用另一种带有关键字 bound
的限制——它检查类型变量的值是否是给定类型的子类型(在我们的例子中,Number
,这是一个基 class 用于 Python).
中的所有数值类型
更多示例:mypy documentation and PEP 484.
工作测试:
from numbers import Number
from typing import Tuple, TypeVar
import numpy as np
from typeguard import typechecked
T = TypeVar('T', bound=Number)
@typechecked
def foo(data: Tuple[T, T, T]):
print('expected OK:', data)
for data in (
(1, 2, 3), # ok
(1.0, 2.0, 3.0), # ok
(1, 2.0, 3), # TypeError
(1.0, 2.0, 3), # TypeError
(1.0, 2.0, np.float64(3.0)), # ok (yes!)
(1, 2.0, np.float32(3)), # TypeError
(1, 2.0, np.uint8(3)), # TypeError
):
try:
foo( data )
except TypeError:
print('expected TypeError:', data)
目前,我正在检查具有以下形式的多个(例如三个)任意但相同类型的元组:
from typing import Tuple, Union
Union[Tuple[int, int, int], Tuple[float, float, float]]
我想让这个检查更通用,也允许 numpy
数字类型。 IE。我尝试使用 numbers.Number
:
from numbers import Number
from typing import Tuple
Tuple[Number, Number, Number]
上面的片段也允许混合类型的元组,只要一切都是数字。
我想将元组限制为相同类型的数字。
如何实现?
从技术上讲,这个问题适用于 Python 和类型提示规范本身。然而,正如评论中指出的那样,它的处理是特定于实现的,即 MyPy 不会捕获每个边缘情况 and/or 不一致。就个人而言,我正在使用 运行 时间检查 typeguard 进行测试并在生产中完全停用它们。
您可以将 TypeVar
与 bound
参数一起使用。它允许将类型限制为给定类型的子类型。在您的情况下,类型应该是 Number
:
from numbers import Number
from typing import TypeVar
T = TypeVar('T', bound=Number)
Tuple[T, T, T]
为什么有效?
TypeVar
是一个允许在类型签名中多次使用特定类型的变量。最简单的例子:
from typing import TypeVar, Tuple
T = TypeVar('T')
R = TypeVar('R')
def swap(x: T, y: R) -> Tuple[R, T]:
return y, x
静态类型检查器将推断函数 swap
的参数应该与输出的顺序相同(注意 return 类型 T 将与输入类型 T 相同) .
接下来,引入对 TypeVar
的限制可能会有用。例如,可以将类型变量的值限制为特定类型:TypeVar('T', int, str)
。在这个答案中,我们使用另一种带有关键字 bound
的限制——它检查类型变量的值是否是给定类型的子类型(在我们的例子中,Number
,这是一个基 class 用于 Python).
更多示例:mypy documentation and PEP 484.
工作测试:
from numbers import Number
from typing import Tuple, TypeVar
import numpy as np
from typeguard import typechecked
T = TypeVar('T', bound=Number)
@typechecked
def foo(data: Tuple[T, T, T]):
print('expected OK:', data)
for data in (
(1, 2, 3), # ok
(1.0, 2.0, 3.0), # ok
(1, 2.0, 3), # TypeError
(1.0, 2.0, 3), # TypeError
(1.0, 2.0, np.float64(3.0)), # ok (yes!)
(1, 2.0, np.float32(3)), # TypeError
(1, 2.0, np.uint8(3)), # TypeError
):
try:
foo( data )
except TypeError:
print('expected TypeError:', data)