es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

mypy: ¿Cuál es la necesidad de covariante en este TypeVar?

U = TypeVar("U", covariant=True)

class IterableAndSized(Protocol[U], Sized, Iterable[U]): ...

Quiero crear un protocolo como el anterior que utilice las clases base abstractas Sized e Iterable para definir un tipo aceptable; por ejemplo,

T = TypeVar("T")

def tailvalue(index_from_rear: int, x: Iterable[T] | IterableAndSized[T]) -> T:
    if isinstance(x, Sized):
        for i, val in enumerate(x):
            if i == len(x) - index_from_rear:
                return val

    return list(x)[-index_from_rear]

esto puede ayudar a optimizar la obtención de valores cerca del final de una expresión de generador.

¿Por qué necesito TypeVar("U", covariant=True) en lugar de simplemente TypeVar("U") allí? Si he entendido correctamente, significa que se permiten subtipos o algo así, estoy seguro de que está bien, pero no sé por qué es un requisito aquí.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La razón de usar TypeVar("U", covariant=True) en lugar de solo TypeVar("U") es permitir que se usen subtipos. En otras palabras, si existe una jerarquía de tipos donde un subtipo es una versión más específica de un tipo padre, entonces la bandera covariant=True permite que se use el subtipo en lugar del tipo padre. Esto es útil al definir un protocolo que necesita aceptar tipos más específicos sin tener que redefinir todo el protocolo para cada tipo específico. En el ejemplo dado, el protocolo IterableAndSized se define como un subtipo de las clases base abstractas Sized e Iterable con un tipo genérico U. Al usar TypeVar("U", covariant=True), se permite que se usen tipos más específicos en lugar de U al definir una clase que implementa este protocolo.

Comments are closed.