我有一个字符串列表:
strings = ['a','b','c']
我想声明列表中所有可能的有序对的
Union
类型。硬编码,这看起来像:
Literal
我如何动态定义
CustomType = Literal[
'ab', 'ac', 'aa',
'ba', 'bb', 'bc',
'ca', 'cb', 'cc'
]
这样我就不必手动放置每个组合?
CustomType
我正在考虑以下内容:
但这给出了我的错误:
CustomType = Literal[*permutations(strings)]
激发这个问题的目标是让 Pylance 检测我是否尝试传递不是该集合元素的字符串。
Unpack operator in subscript requires Python 3.11 or newer
Pylance
Unpacked arguments cannot be used in type argument lists
Pylance
The objective motivating this question is to have Pylance detect if I try passing a string that is not an element of that set.
def f(string: CustomType):
...
f('foo') # Pylance will complain
f('ba') # Pylance will permit
不能使用
Literal
动态创建文字字符串的并集,因为
Literal
需要在编译时明确知道文字值。但是,可以使用枚举或自定义类来实现类似的目标。
1. 使用枚举:
from enum import Enum
class CustomType(Enum):
"""所有字符串组合的枚举。"""
aa = 'aa'
ab = 'ab'
ac = 'ac'
ba = 'ba'
bb = 'bb'
bc = 'bc'
ca = 'ca'
cb = 'cb'
cc = 'cc'
def f(string: CustomType):
...
f('foo') # Pylance 会报错
f('ba') # Pylance 会允许
f(CustomType.ba) # 使用枚举成员
这将创建一个名为
CustomType
的枚举,其中包含所有可能的字符串组合。Pylance 将识别这些成员,并可以相应地进行类型检查。
2. 使用自定义类:
from typing import List
STRINGS = ['a', 'b', 'c']
VALID_COMBINATIONS = [''.join(pair) for pair in itertools.product(STRINGS, repeat=2)]
class CustomType:
"""表示有效字符串组合的类。"""
def __init__(self, value: str):
if value not in VALID_COMBINATIONS:
raise ValueError(f"Invalid string combination: {value}")
self.value = value
def __eq__(self, other: object) -> bool:
if isinstance(other, CustomType):
return self.value == other.value
return False
def f(string: CustomType):
...
f('foo') # 会引发 ValueError
f('ba') # 创建一个 CustomType 实例
f(CustomType('ba')) # 显式创建 CustomType 实例
此方法定义了一个自定义类
CustomType
,该类在初始化时检查值是否在有效组合中。这提供了更严格的类型检查,并允许在传递无效值时引发自定义错误。
这两种方法都可以帮助实现所需的行为,并允许 Pylance 检测无效的字符串组合。选择最适合需求和编码风格的方法。
标签:python,python-typing,pyright From: 74075558