Правильные аннотации типа для функции генератора, которые дают срезы данной последовательности?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Правильные аннотации типа для функции генератора, которые дают срезы данной последовательности?

Сообщение Anonymous »

Я использую Python 3.13 и имею эту функцию: < /p>

Код: Выделить всё

def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Я хочу дать аннотации типа типа, чтобы указать, что он может работать с байтами , Bytearray или общей коллекцией. Sevestence любого рода, и пусть тип возврата будет генератором точного входного типа. Я не хочу, чтобы тип возврата был типом объединения всех возможных входов (например, байт | Bytearray | sequence [t] ), потому что это чрезмерно; Я хочу точный тип, который я случайно вставил, чтобы вернуться на другой конец. Вызов chunk на байтах должен возвращать генератор [Bytes] и т. Д.

Код: Выделить всё

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))
Но это имеет проблему ковариации- тип возврата- это последовательность [t] , а не байты , и пирайт жалуется, когда я передаю возврат в функцию, которая принимает байт (параметр>

Код: Выделить всё

def print_bytes(b: bytes) -> None: ...
):

Код: Выделить всё

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>
Итак, я попытался использовать ограничение типа: "chunk
может взять любую последовательность и возвращает генератор такого типа. »

Код: Выделить всё

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>
На этот раз пирайт жалуется на саму функцию: < /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)
Я признаю, что не полностью понимает здесь жалобу- мы установили с ограничением типа, что t является последовательности , но пирайт не любит, и я предполагаю, что мой код виноват.

Код: Выделить всё

@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))
В данном случае Pyright может выбрать правильную перегрузку для всех моих применений, но это немного глупо- есть 2x как код типирования, как и фактический код реализации!>

Подробнее здесь: https://stackoverflow.com/questions/796 ... -the-given
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»