【发布时间】:2021-03-30 15:56:18
【问题描述】:
我有一个函数可以验证它的参数是否只接受给定的有效选项列表中的值。在打字方面,我使用 Literal 类型别名来反映这种行为,如下所示:
from typing import Literal
VALID_ARGUMENTS = ['foo', 'bar']
Argument = Literal['foo', 'bar']
def func(argument: 'Argument') -> None:
if argument not in VALID_ARGUMENTS:
raise ValueError(
f'argument must be one of {VALID_ARGUMENTS}'
)
# ...
这违反了 DRY 原则,因为我必须在我的 Literal 类型的定义中重写有效参数列表,即使它已经存储在变量 VALID_ARGUMENTS 中。 如何在给定VALID_ARGUMENTS 变量的情况下动态创建Argument Literal 类型?
以下事情不起作用:
from typing import Literal, Union, NewType
Argument = Literal[*VALID_ARGUMENTS] # SyntaxError: invalid syntax
Argument = Literal[VALID_ARGUMENTS] # Parameters to generic types must be types
Argument = Literal[Union[VALID_ARGUMENTS]] # TypeError: Union[arg, ...]: each arg must be a type. Got ['foo', 'bar'].
Argument = NewType(
'Argument',
Union[
Literal[valid_argument]
for valid_argument in VALID_ARGUMENTS
]
) # Expected type 'Type[_T]', got 'list' instead
那么,怎么做呢?还是根本做不到?
【问题讨论】:
-
你几乎明白了!
Literal接受类型或文字的元组。ValidArgs = Literal[tuple(VALID_ARGUMENTS)]可以。但正如已经提到的,它击败了静态类型检查器。
标签: python type-hinting python-typing