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.

Cómo escribir correctamente los métodos de Python que devuelven un diccionario con una instancia de tipo genérico y su propiedad de tipo genérico.

Tengo la siguiente función Python y quiero escribirla de tal forma que mypy entienda el tipo de retorno como un diccionario, con el tipo de valor como el tipo de ítem y el tipo de identificación como el tipo de clave:

def id_map(items):
    return {item.id: item for item in items}

El enfoque actual se ve así:

from typing import Iterable, Protocol, TypeVar

S = TypeVar("S", covariant=True, bound="ClassWithId")
T = TypeVar("T", covariant=True)

class ClassWithId(Protocol[S, T]):
    def new(cls: type[S], args: Any, **kwargs: Any) -> "ClassWithId[S, T]":
        ...

@property
def id(self: S) -> T:
    ...

def id_map(items: Iterable[ClassWithId[S, T]]) -> dict[T, S]:
    return {item.id: cast(S, item) for item in items}

Esto resulta actualmente en el tipo builtins.dict[Any, Any]. No puedo pensar en una implementación diferente que haga que esto funcione. Me pregunto si esto es posible utilizando mypy.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, es posible escribir la función id_map de tal manera que mypy comprenda que el tipo de retorno es un diccionario cuyos valores corresponden al tipo de los elementos y las claves corresponden al tipo del id.

    Aquí hay un ejemplo de cómo hacerlo:

    from typing import Any, Dict, Iterable, TypeVar
    
    T = TypeVar('T')
    S = TypeVar('S', bound='ClassWithId')
    
    class ClassWithId:
        def __init__(self, id_: T) -> None:
            self.id = id_
    
    def id_map(items: Iterable[S]) -> Dict[T, S]:
        return {item.id: item for item in items}
    

    En este ejemplo, definimos dos variables de tipo, T y S, donde T representa el tipo de la clave y S representa el tipo de los elementos en la entrada iterable items. Luego definimos una clase ClassWithId con un atributo id_ de tipo T, y finalmente, definimos la función id_map con el tipo de retorno deseado de Dict[T, S].

    Con esta implementación, mypy puede inferir correctamente el tipo de retorno Dict[T, S] para la función id_map.

Comments are closed.