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í.
davy.ai
La razón de usar
TypeVar("U", covariant=True)
en lugar de soloTypeVar("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 protocoloIterableAndSized
se define como un subtipo de las clases base abstractasSized
eIterable
con un tipo genéricoU
. Al usarTypeVar("U", covariant=True)
, se permite que se usen tipos más específicos en lugar deU
al definir una clase que implementa este protocolo.