Richtige Typanmerkungen für die Generatorfunktion, die Schnitte der angegebenen Sequenz hervorruft?
Posted: 02 May 2025, 04:41
Ich verwende Python 3.13 und habe diese Funktion: < /p>
Ich möchte ihm Annotationen geben, um anzuzeigen, dass es mit Bytes , bytearray oder einer allgemeinen Sammlung arbeiten kann. Ich möchte nicht, dass der Rückgabetyp ein Gewerkschaftstyp aller möglichen Eingaben (z. B. Bytes | Bytearray | Sequenz [t] ) ist, da dies übermäßig weit ist; Ich möchte, dass der genaue Typ, den ich zufällig einbringe, wieder am anderen Ende herauskommt. Aufrufen von Chunk auf einem Bytes sollte Generator [Bytes] usw. zurückgeben,
Da Bytes und Bytearray beide an die Sequenz [t] entsprechen, war mein erster Versuch:
, aber dies hat eine Kovarianzprobleme- Der Rückgabetyp ist Sequenz [t] , nicht Bytes , und Pyright beschwert):
kann eine beliebige Sequenz nehmen und einen Generator dieses Typs zurückgeben. "
Ich gebe zu, die Beschwerde hier nicht vollständig zu verstehen. Wir haben über die Typ-Einschränkung festgelegt, dass t eine Sequenz ist, aber Pyright mag es nicht und ich gehe davon aus, dass mein Code schuld ist.
In diesem Fall kann Pyright die richtige Überladung für alle meine Verwendungen auswählen, aber dies fühlt sich ein wenig albern an- es gibt 2x so viel Tippcode wie den tatsächlichen Implementierungscode!>
Code: Select all
def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Da Bytes und Bytearray beide an die Sequenz [t] entsprechen, war mein erster Versuch:
Code: Select all
def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Code: Select all
def print_bytes(b: bytes) -> None: ...
Code: Select all
error: Argument of type "Sequence[int]" cannot be assigned to parameter "b" of type "bytes" in function "print_bytes"
"Sequence[int]" is not assignable to "bytes" (reportArgumentType)
< /code>
Dann habe ich versucht, eine Typ -Einschränkung zu verwenden: "chunk
Code: Select all
def chunk[T: Sequence](data: T, chunk_size: int) -> Generator[T]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
< /code>
Diesmal beschwert sich Pyright über die Funktion selbst: < /p>
error: Return type of generator function must be compatible with "Generator[Sequence[Unknown], Any, Any]"
"Generator[Sequence[Unknown], None, Unknown]" is not assignable to "Generator[T@chunk, None, None]"
Type parameter "_YieldT_co@Generator" is covariant, but "Sequence[Unknown]" is not a subtype of "T@chunk"
Type "Sequence[Unknown]" is not assignable to type "T@chunk" (reportReturnType)
Code: Select all
@typing.overload
def chunk[T: bytes | bytearray](data: T, chunk_size: int) -> Generator[T]: ...
@typing.overload
def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]: ...
def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))