How can I get the literal value out of a 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')
The code above type checks since 'add'
is of type Literal['add']
, but at runtime, it raises a ValueError since the string 'add'
is not the same as typing.Literal['add']
.
How can I, at runtime, reuse the literals that I defined at type level?
The typing
module provides a function get_args
which retrieves the arguments with which your Literal
was initialized.
>>> from typing import Literal, get_args
>>> l = Literal['add', 'mul']
>>> get_args(l)
('add', 'mul')
However, I don't think you gain anything by using a Literal
for what you propose. What would make more sense to me is to use the strings themselves, and then maybe define a Literal
for the very strict purpose of validating that arguments belong to this set of strings.
>>> 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]
Remember, a type annotation is essentially a specialized type definition, not a value. It restricts which values are allowed to pass through, but by itself it merely implements a constraint -- a filter which rejects values which you don't want to allow. And as illustrated above, its argument is a set of allowed values, so the constraint alone merely specifies which values it will accept, but the actual value only comes when you concretely use it to validate a value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With