Wie erstelle ich einen variadischen generischen Container mit heterogenen Typen in Python 3.13 unter Verwendung von PEP
Posted: 03 Jan 2025, 18:32
Ich experimentiere mit PEP 646 Variadic Generics und PEP 695 Class/Function Scoped TypeVars in Python 3.13. Mein Ziel ist es, einen heterogenen Container zu erstellen, der Elemente (in diesem Beispiel Funktionen) speichert, die jeweils einen anderen Typ zurückgeben – und dabei Any vermeidet.
Hier ist ein vereinfachtes Beispiel :
Problem:
< ul>
[*]run_all() gibt ein vollständig typisiertes Tupel[*Ts] zurück,
[*]Jeder Index hat seinen genauen Typ (z. B. ops[0] ist Operation[int ]).
Gibt es eine Best Practice für einen generischen Variadic-Container in Python 3.13, die diese Fehler vermeidet? Oder ist dies derzeit eine Einschränkung in der Werkzeugausstattung? Ich gewöhne mich jetzt schon an dieses „neue“ Ding „TypeVarTuple“.
Hier ist ein vereinfachtes Beispiel :
Code: Select all
from typing import Callable
class Operation[R]:
"""Encapsulates a function returning type R."""
def __init__(self, fn: Callable[[], R]) -> None:
self._fn = fn
def run(self) -> R:
return self._fn()
class OperationSequence[*Ts]:
"""
A typed-tuple container for Operation objects,
each possibly returning a different type in Ts.
For example, OperationSequence[int, str] means
item[0] returns int, item[1] returns str, etc.
"""
def __init__(self, *ops: Operation[*Ts]) -> None:
self._ops = ops # storing them in a tuple
def __getitem__(self, index: int) -> Operation[Ts[index]]: # What do do here?
return self._ops[index]
def __len__(self) -> int:
return len(self._ops)
def run_all(self) -> tuple[*Ts]:
# I'd like this to return e.g. tuple[int, str]
return tuple(op.run() for op in self._ops)
# Example usage
def get_number() -> int:
return 42
def get_text() -> str:
return "Hello"
ops = OperationSequence(
Operation(get_number), # returns int
Operation(get_text), # returns str
)
# I'd like mypy/pyright to infer:
# ops.run_all() -> tuple[int, str]
# ops[0].run() -> int
# ops[1].run() -> str
print(ops.run_all())
- *Konstruktor: Ich erhalte Fehlermeldungen wie *„TypeVarTuple ist nicht in diesem Kontext zulässig“ in mypy/pyright.
- *getitem: Ich sehe *„Type 'Operation[*Ts@OperationSequence]' kann nicht zurückgegeben werden Typ 'Operation[Ts[index]]'“ oder „TypeVar 'Ts@OperationSequence' ist nicht abonnierbar“ usw.
< ul>
[*]run_all() gibt ein vollständig typisiertes Tupel[*Ts] zurück,
[*]Jeder Index hat seinen genauen Typ (z. B. ops[0] ist Operation[int ]).
Gibt es eine Best Practice für einen generischen Variadic-Container in Python 3.13, die diese Fehler vermeidet? Oder ist dies derzeit eine Einschränkung in der Werkzeugausstattung? Ich gewöhne mich jetzt schon an dieses „neue“ Ding „TypeVarTuple“.