¿Existen realmente tipos de unión en python?

Como Python se escribe dinámicamente, por supuesto, podemos hacer algo como esto:

def f(x): return 2 if x else "s" 

¿Pero es la forma en que Python fue en realidad destinado a ser utilizado? o en otras palabras, ¿existen tipos de unión en el sentido que lo hacen en la raqueta, por ejemplo? O solo los usamos así:

 def f(x): if x: return "x" 

¿Dónde está la única “unión” que necesitamos con ninguna?

La escritura de unión solo es necesaria cuando tiene un lenguaje tipado estáticamente, ya que necesita declarar que un objeto puede devolver uno de varios tipos (en su caso, int o str , o en el otro ejemplo, str o NoneType ).

Python solo se ocupa de objetos , por lo que nunca es necesario considerar “tipos de unión”. Las funciones de Python devuelven lo que devuelven, si el progtwigdor desea devolver diferentes tipos para diferentes resultados, entonces esa es su elección. La elección es, entonces, una elección de architecture, y no hace ninguna diferencia para el intérprete de Python (por lo que no hay nada que “comparar” aquí).

Python 3.5 introduce un estándar para crear sugerencias de tipo opcionales, y ese estándar incluye Optional[...] anotaciones de Union[...] y Optional[...] .

el tipo en sí no existe porque Python es solo un lenguaje de tipo dynamic, sin embargo, en las versiones más nuevas de Python, Union Type es una opción para Type Hinting ,

 from typing import Union,TypeVar T = TypeVar('T') def f(x: T) -> Union[str, None]: if x: return "x" 

puede usar eso para anotar su código, habilitando así la comprobación de syntax de nivel IDE / Editor.

Aquí hay un par de opciones para lidiar con los casos de uso donde necesita un tipo de unión / sum etiquetado en Python:

  • Enum + Tuplas

     from enum import Enum Token = Enum('Token', ['Number', 'Operator', 'Identifier', 'Space', 'Expression']) (Token.Number, 42) # int type (Token.Operator, '+') # str type 1 (Token.Identifier, 'foo') # str type 2 (Token.Space, ) # no data (Token.Expression, 'lambda', 'x', 'x+x') # multiple data 
  • isinstance

     if isinstance(token, int): # Number type if isinstance(token, str): # Identifier type 
  • módulo de sumtypes

Todos estos enfoques tienen sus diversos inconvenientes, por supuesto.

Añadiendo a la respuesta de @MartijnPieters:

¿Pero es la forma en que Python fue en realidad destinado a ser utilizado?

Volver tipos diferentes según el parámetro nunca es una buena práctica en ningún idioma. Esto hace que las pruebas, el mantenimiento y la extensión del código sean realmente difíciles, y en mi humilde opinión es un antipatrón (pero, por supuesto, a veces es un mal necesario). Los resultados deben estar relacionados al menos a través de una interfaz común.

La única razón por la que la union se introdujo en C se debió a la ganancia de rendimiento. Pero en Python no tienes esta ganancia de rendimiento debido a la naturaleza dinámica del lenguaje (como notó Martijn). En realidad, la introducción de un union reduciría el rendimiento, ya que el tamaño del union es siempre el tamaño del miembro más grande. Por lo tanto, Python nunca tendrá una union tipo C.