Python 3.8.6中如何从自定义Literal类型随机选取选项?
解决Python 3.8中从Literal类型随机选值的问题
你定义了如下Literal类型别名:
from typing import Literal, get_args _ACTIONS = Literal["pasteCharAt", "copyCharAt", "deleteCharAt", "replaceCharAt", "selectAll", "deleteAll", "copyAll", "pasteAllAt", "click", "moveLeft", "moveRight"]
尝试直接用random.choice(_ACTIONS)或者random.choice(list(_ACTIONS))时都触发了错误:
- 第一种写法报错:
File "C:\python38\lib\random.py", line 288, in choice i = self._randbelow(len(seq)) TypeError: object of type '_GenericAlias' has no len()
- 第二种写法报错:
File "C:\python38\lib\typing.py", line 261, in inner return func(*args, **kwds) File "C:\python38\lib\typing.py", line 685, in __getitem__ params = tuple(_type_check(p, msg) for p in params) File "C:\python38\lib\typing.py", line 685, in <genexpr> params = tuple(_type_check(p, msg) for p in params) File "C:\python38\lib\typing.py", line 149, in _type_check raise TypeError(f"{msg} Got {arg!r:.100}.") TypeError: Parameters to generic types must be types. Got 0.
错误原因
_ACTIONS是类型别名(属于_GenericAlias类型),不是可迭代的序列对象,所以random.choice无法直接处理它;而list(_ACTIONS)会错误触发类型的__getitem__方法,导致参数校验失败。
解决方案
你已经导入了get_args函数,它可以提取出Literal类型定义中的所有选项参数,返回一个元组。直接用这个元组作为random.choice的输入即可:
import random from typing import Literal, get_args _ACTIONS = Literal["pasteCharAt", "copyCharAt", "deleteCharAt", "replaceCharAt", "selectAll", "deleteAll", "copyAll", "pasteAllAt", "click", "moveLeft", "moveRight"] # 获取Literal的所有选项 action_options = get_args(_ACTIONS) # 随机选择一个值 random_action = random.choice(action_options) print(f'random.choice(action_options) = {random_action}')
这个方法在Python 3.8+版本中都能正常工作,因为get_args在3.8及以上版本已经支持提取Literal的参数。
内容的提问来源于stack exchange,提问作者Gen Eva
相关产品推荐
相关产品推荐

