Можете ли вы сопоставить шаблоны с типами Python?
Я видел простые примеры:
import builtins
match x:
case builtins.str:
print("matched str")
case buildins.int:
print("matched int")
Но мне бы хотелось сопоставить шаблон для вложенного типа, что-то вроде Annotated[Optional[Literal["a", "b", "c"]], "something here"] - возможно ли это?
Другими словами, если бы вы использовали if вместо match, вы бы написали if x == Annotated[Optional[Literal["a", "b", "c"]], "something here"] или что-то другое?
Я хочу сопоставить, является ли x буквально объектом аннотации с этой структурой, и в идеале разрушить его.






Сопоставление с образцом, по сути, сводится к цепочке вызовов isinstance и ==, среди прочего. Это означает, что если вы можете выразить Annotated[Optional[Literal["a", "b", "c"]], "something here"] как серию вызовов isinstance, == и т. д., вы можете выполнить сопоставление с образцом.
Проблема с попыткой сопоставления шаблонов элементов из typing заключается в том, что типы объектов typing.Annotated[...], typing.Optional[...] и т. д. являются деталями реализации (они являются подклассами typing._GenericAlias, а их переменные экземпляра и свойства не являются общедоступными), тогда как сопоставление с образцом (в частности, шаблоны классов) — это стиль, который идеально работает при программировании с использованием общедоступного API. Если вас не волнует доступ к деталям реализации, это может сработать:
import types
from typing import *
x = Annotated[Optional[Literal["a", "b", "c"]], "something here"]
AnnotatedAlias = type(Annotated[Any, Any])
UnionAlias = type(Union[Any, None])
LiteralAlias = type(Literal[None])
match x:
case AnnotatedAlias(
__args__=(
UnionAlias(__args__=(LiteralAlias(__args__=("a", "b", "c")), types.NoneType)),
)
):
print("x matched")
Я думаю, что NoneType будет рассматриваться как шаблон захвата, а не шаблон значения - он будет соответствовать чему угодно и назначать это NoneType.
@user2357112 user2357112 хороший улов, спасибо!
Вы хотите сопоставить, был ли
xаннотирован этой аннотацией, или вы хотите сопоставить, является лиxбуквально объектом аннотации с этой структурой?