Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

341
Views
¿Cómo escribir correctamente los métodos de Python que devuelven un dictado con una instancia de tipo genérico y su propiedad de tipo genérico?

Tengo la siguiente función de Python y quiero escribirla de manera que mypy entienda el tipo de devolución como un diccionario, con el tipo de elemento como tipo de valor y el tipo de identificación como 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}

Actualmente, esto da como resultado el tipo builtins.dict[Any, Any] . No puedo pensar en una implementación diferente que haría que eso funcione. Me pregunto si esto es posible usando mypy.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

TLDR: elimine la variable de tipo propio S . No es necesario, pero conduce a una relación de tipo que es poco probable que los verificadores de tipo entiendan.

 class ClassWithId(Protocol[T]): @property def id(self) -> T: ...

Las variables de tipo se pueden utilizar de dos formas: como variables inferidas en una llamada o como variables declaradas en un tipo genérico. Utilice el primero para los tipos que están restringidos por el contexto de uso y el último para los tipos que deben ser coherentes en toda una clase.

El tipo S var es un tipo Self ; esto siempre se puede inferir del uso y no es necesario repetirlo en el tipo mismo. De lo contrario, construye un tipo recursivo que probablemente confunda a los verificadores de tipos actuales.

Eliminar S del genérico/protocolo muestra que en realidad no se usa para ninguna relación de tipo: la T está totalmente restringida por la clase ClassWithId[T] . No es necesario referirse a S para definir ninguna relación entre entrada y salida.

 class ClassWithId(Protocol[T]): @property def id(self: S) -> T: ... # ^ defined by generic class, not S

Observe cómo id_map tampoco depende de S : conocer T o ClassWithId[T] es suficiente para conocer al otro. Como resultado, se puede eliminar S por completo.

 T = TypeVar("T", covariant=True) class ClassWithId(Protocol[T]): @property def id(self) -> T: ... def id_map(items: Iterable[ClassWithId[T]]) -> dict[T, ClassWithId[T]]: return {item.id: item for item in items}

Si se supone que id_map conserva el ClassWithId[T] exacto y no solo el protocolo, esto corresponde a un tipo más alto . En principio, esto se expresa mediante una variable Tipo con un límite del protocolo.

 CWI = TypeVar("CWI", bound=ClassWithId) def id_map(items: Iterable[CWI[T]]) -> dict[T, CWI[T]]: return {item.id: item for item in items}

Sin embargo, MyPy no admite tipos de tipos superiores en este momento .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!