在运行时从 python 文字类型中获取文字?

Lud*_*igH 9 python types typing literals python-3.8

如何Literal[]从 from 中获取文字值typing

from typing import Literal, Union

Add = Literal['add']
Multiply = Literal['mul']
Action = Union[Add,Multiply]

def do(a: Action):
    if a == Add:
        print("Adding!")
    elif a == Multiply:
        print("Multiplying!")
    else:
        raise ValueError

do('add')
Run Code Online (Sandbox Code Playgroud)

上面的代码类型检查,因为'add'是 type Literal['add'],但在运行时,它会引发 ValueError 因为字符串'add'typing.Literal['add'].

我如何在运行时重用我在类型级别定义的文字?

tri*_*eee 15

typing模块提供了一个函数get_args,用于检索Literal初始化您的参数。

>>> from typing import Literal, get_args
>>> l = Literal['add', 'mul']
>>> get_args(l)
('add', 'mul')
Run Code Online (Sandbox Code Playgroud)

但是,我认为将 aLiteral用于您的建议并不会带来任何好处。对我来说更有意义的是使用字符串本身,然后可能Literal为了验证参数属于这组字符串的非常严格的目的而定义 a 。

>>> def my_multiply(*args):
...    print("Multiplying {0}!".format(args))
...
>>> def my_add(*args):
...    print("Adding {0}!".format(args))
...
>>> op = {'mul': my_multiply, 'add': my_add}
>>> def do(action: Literal[list(op.keys())]):
...    return op[action]
Run Code Online (Sandbox Code Playgroud)

请记住,类型注释本质上是一个专门的类型定义,而不是一个值。它限制允许通过哪些值,但它本身只是实现了一个约束——一个拒绝你不想允许的值的过滤器。并且如上所示,它的参数是一组允许的值,因此约束本身仅指定它将接受哪些值,但实际值只有在您具体使用它来验证值时才会出现。

  • python 标准不允许动态文字类型 https://www.python.org/dev/peps/pep-0586/#illegal-parameters-for-literal-at-type-check-time (10认同)
  • `Litera[list...]` 是有效的 Python 吗?mypy 给我“错误:无效类型:文字[...]不能包含任意表达式” (2认同)