Python

Equivalencias idiomáticas entre Kotlin y Python. Kotlin se presenta como referencia en cada concepto.

Tipos paramétricos y convenciones del lenguaje

Genéricos, operadores y rangos cambian de sintaxis entre ecosistemas, pero las preguntas de diseño detrás son las mismas: qué varía, qué se comprueba y cuándo.

Equivalencia desde Kotlin

Genéricos y varianza

Cercana

En Python, TypeVar covariante o contravariante para verificadores estáticos expresa la responsabilidad del fixture: Source<T> produce valores y Sink<T> los consume sin mezclar ambas responsabilidades.

Referencia Kotlin: Source<out T> es covariante y Sink<in T> es contravariante.

Mecanismo
TypeVar covariante o contravariante para verificadores estáticos
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar TypeVar covariante o contravariante para verificadores estáticos.
Recomendación
Expón el contrato del fixture y usa TypeVar covariante o contravariante para verificadores estáticos solo para la garantía que realmente ofrece.

Diferencias relevantes

  • La varianza puede declararse, proyectarse en el uso o no tener una noción de subtipado equivalente.
  • La forma idiomática de Python debe conservarse aunque la sintaxis difiera de Kotlin.

Source<T> produce valores y Sink<T> los consume sin mezclar ambas responsabilidades.

T_co = TypeVar("T_co", covariant=True)
class Source(Protocol[T_co]):
    def get(self) -> T_co: ...

Fuentes

Equivalencia desde Kotlin

Operadores

Cercana

En Python, método especial __contains__, que habilita el operador in expresa la responsabilidad del fixture: Comprueba si un precio de 79.9 cae dentro de un rango válido entre 50.0 y 100.0.

Referencia Kotlin: operator fun contains permite escribir price in range para una pertenencia definida por el dominio.

Mecanismo
método especial __contains__, que habilita el operador in
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar método especial __contains__, que habilita el operador in.
Recomendación
Expón el contrato del fixture y usa método especial __contains__, que habilita el operador in solo para la garantía que realmente ofrece.

Diferencias relevantes

  • Muy pocos lenguajes permiten definir el operador de pertenencia (in) sobre un tipo propio; la mayoría exige un método con nombre como contains.
  • La forma idiomática de Python debe conservarse aunque la sintaxis difiera de Kotlin.

Comprueba si un precio de 79.9 cae dentro de un rango válido entre 50.0 y 100.0.

@dataclass(frozen=True)
class PriceRange:
    min: float
    max: float
    def __contains__(self, price: float) -> bool:
        return self.min <= price <= self.max

79.9 in PriceRange(50.0, 100.0)

__call__ habilita el operador de invocación sobre una instancia.

class MinimumPrice:
    def __init__(self, threshold: float) -> None:
        self.threshold = threshold
    def __call__(self, price: float) -> bool:
        return price >= self.threshold

MinimumPrice(10.0)(79.9)

Fuentes

Equivalencia desde Kotlin

Rangos

Cercana

En Python, range(1, limit + 1) con extremo superior exclusivo expresa la responsabilidad del fixture: Itera los enteros desde 1 hasta limit, incluyendo limit.

Referencia Kotlin: 1..limit representa una progresión de extremos inclusivos.

Mecanismo
range(1, limit + 1) con extremo superior exclusivo
Riesgo de diseño
Copiar la sintaxis de Kotlin en vez de usar range(1, limit + 1) con extremo superior exclusivo.
Recomendación
Expón el contrato del fixture y usa range(1, limit + 1) con extremo superior exclusivo solo para la garantía que realmente ofrece.

Diferencias relevantes

  • Un rango puede ser una colección reutilizable, un iterable perezoso o solo una forma de construir un bucle.
  • La forma idiomática de Python debe conservarse aunque la sintaxis difiera de Kotlin.

Itera los enteros desde 1 hasta limit, incluyendo limit.

for value in range(1, limit + 1):
    print(value)

Fuentes