Cómo especificar múltiples tipos de retorno usando sugerencias de tipo

205

Tengo una función en python que puede devolver a boolo a list. ¿Hay alguna manera de especificar los tipos de retorno utilizando sugerencias de tipo?

Por ejemplo, ¿es esta la forma correcta de hacerlo?

def foo(id) -> list or bool:
      ...
Yahya Uddin
fuente
55
¿Cómo terminas con una lista o un booleano?
Padraic Cunningham
11
@PadraicCunningham Quizás la implementación es que te enviaré mi ID, tú me envías una lista o un booleano : D
Bhargav Rao
probablemente esa es una implementación débil
Sławomir Lenart
@PadraicCunningham Polymorphism. Si su función realiza una verificación en la entrada, sea lo que sea, desea obtener un valor booleano cuando alimenta una variable u obtener una lista de valores booleanos cuando alimenta una lista de variables.
Guimoute

Respuestas:

282

De la documentación

clase typing.Union

Tipo de unión; Unión [X, Y] significa X o Y.

Por lo tanto, la forma correcta de representar más de un tipo de datos de retorno es

from typing import Union


def foo(client_id: str) -> Union[list,bool]

Pero tenga en cuenta que la escritura no se aplica. Python continúa siendo un lenguaje de tipo dinámico. La sintaxis de la anotación se ha desarrollado para ayudar durante el desarrollo del código antes de su lanzamiento a producción. Como dice PEP 484, "no se realiza ninguna verificación de tipo en tiempo de ejecución".

>>> def foo(a:str) -> list:
...     return("Works")
... 
>>> foo(1)
'Works'

Como puede ver, estoy pasando un valor int y devolviendo un str. Sin embargo __annotations__, se establecerá en los valores respectivos.

>>> foo.__annotations__ 
{'return': <class 'list'>, 'a': <class 'str'>}

Consulte PEP 483 para obtener más información sobre sugerencias de tipo. Consulte también ¿Qué son las sugerencias de tipo en Python 3.5 ?

Tenga en cuenta que esto solo está disponible para Python 3.5 y versiones posteriores. Esto se menciona claramente en PEP 484 .

Bhargav Rao
fuente
¿Hay un equivalente en Python 3.4
Yahya Uddin
1
@YahyaUddin Nope - PEP 484 : '(... Es solo para Python3.5 hacia arriba.
Bhargav Rao
1
@YahyaUddin Muy sorprendente. ¿Quiso decir Anotaciones de funciones por casualidad?
Bhargav Rao
2
Déjame ver si tengo esto. Python 3.4 tiene anotaciones de función que no hacen nada más que anotar que NO se aplica. Pero en Python 3.5 esta es la verificación de tipo real.
Yahya Uddin
1
@BhargavRao, ¡perdón por eso! Simplemente sentí que era demasiado importante dejarlo en la sección de comentarios.
Bobort
26

La declaración def foo(client_id: str) -> list or bool:cuando se evalúa es equivalente def foo(client_id: str) -> list:y, por lo tanto, no hará lo que desea.

La forma nativa de describir una pista de tipo "A o B" es Unión (gracias a Bhargav Rao):

def foo(client_id: str) -> Union[list, bool]:

No quiero ser el tipo "¿Por qué quieres hacer esto?", Pero tal vez tener 2 tipos de retorno no es lo que quieres:

Si desea devolver un bool para indicar algún tipo de caso de error especial, considere usar Excepciones en su lugar. Si desea devolver un valor bool como un valor especial, tal vez una lista vacía sería una buena representación. También puede indicar que Nonepodría devolverse conOptional[list]

Felk
fuente
66
Hay usos en los que devolver múltiples tipos puede ser lo que desea: por ejemplo, si necesita devolver uno de algún conjunto de subtipos, pero no otros subtipos, o si está intentando procesar datos y desea devolver el formulario sin procesar si el procesamiento no es No disponible. Además, si está envolviendo código heredado, puede ser bastante útil, ya que ayuda al proceso de actualización y / o ve lugares incómodos.
Nathaniel Ford
Las excepciones y la idea de la lista vacía también fueron útiles. gracias
Yahya Uddin
20

En caso de que alguien aterrice aquí en busca de "¿cómo especificar tipos de valores de retorno múltiples?", Use Tuple[type_value1, ..., type_valueN]

from typing import Tuple

def f() -> Tuple[dict, str]:
    a = {1: 2}
    b = "hello"
    return a, b

Más información: https://code-examples.net/en/q/2651e60

Anton Khodak
fuente