En python 3.x, es común usar la anotación de tipo de retorno de una función, como:
def foo() -> str:
return "bar"
¿Cuál es la anotación correcta para el tipo “vacío”?
Estoy considerando 3 opciones:
def foo() -> None:
- no es lógico en mi opinión, porque
None
no es un tipo,
def foo() -> type(None):
- usando la mejor sintaxis que conozco para obtener
NoneType
,
def foo():
- omita la información de tipo de retorno explícito.
La opción 2 me parece la más lógica, pero ya he visto algunos casos de la 1.
Esto es directo de PEP 484 — Sugerencias de tipo documentación:
Cuando se usa en una sugerencia de tipo, la expresión None
se considera equivalente a type(None)
.
Y, como puede ver, la mayoría de los ejemplos usan None
como tipo de retorno.
TLDR: El equivalente idiomático de un void
la anotación de tipo de retorno es -> None
.
def foo() -> None:
...
Esto coincide con que una función sin return
o simplemente un desnudo return
evalúa a None
.
def void_func(): # unannotated void function
pass
print(void_func()) # None
Omitir el tipo de retorno no no significa que no hay valor de retorno. según PEP 484:
Para una función marcada, la anotación predeterminada para los argumentos y para el tipo de retorno es Any
.
Esto significa que el valor se considera de tipo dinámico y estático. admite cualquier operación. Ese es prácticamente el significado opuesto de void
.
La sugerencia de tipo en Python no requiere estrictamente tipos reales. Por ejemplo, las anotaciones pueden usar cadenas de nombres de tipo: Union[str, int]
, Union[str, 'int']
, 'Union[str, int]'
y varias variantes son equivalentes.
Del mismo modo, la anotación de tipo None
se considera significar “es de NoneType
“. Esto se puede usar en otras situaciones, así como en tipos de devolución, aunque lo verá con mayor frecuencia como una anotación de tipo de devolución:
bar : None
def foo(baz: None) -> None:
return None
Esto también se aplica a los tipos genéricos. Por ejemplo, puedes usar None
en Generator[int, None, None]
para indicar que un generador no toma ni devuelve valores.
Aunque PEP 484 sugiere que None
medio type(None)
tú no debe use la última forma explícitamente. La especificación de sugerencia de tipo no no incluir cualquier forma de type(...)
. Esta es técnicamente una expresión de tiempo de ejecución, y su soporte depende completamente del verificador de tipos. El proyecto mypy es considerando si eliminar el soporte por type(None)
y eliminarlo de 484 también.
O tal vez deberíamos actualizar PEP 484 para no sugerir que type(None)
es válido como un tipo, y None
es la única ortografía correcta? Debería haber una, y preferiblemente solo una, forma obvia de hacerlo, etc.
— JukkaL, 18 de mayo de 2018
FWIW, Python no tiene funciones con
void
tipo de retorno. Cualquier función (o rama en una función) sin un explícitoreturn
regresaráNone
. Supongo que el OP entiende que este comentario es principalmente para el beneficio de futuros lectores…– PM 2 Ring
22 de abril de 2016 a las 15:47
Bueno, esta pregunta no es tan popular como “¿por qué mi función devuelve Ninguno en Python?” (Hice esta pregunta), por lo que probablemente la mayoría de los lectores ya conocen el comportamiento predeterminado. El dilema 1 vs 2 se resuelve en la respuesta. Pero ¿y 3? Para los “procedimientos”, en realidad preferiría la opción 3, sin desorden inútil (después de todo, esta función no devuelve nada).
– Tomasz Gandor
30 de mayo de 2018 a las 7:41
@TomaszGandor De acuerdo. Cuando una función o un método no contiene declaración de devolución, no es necesario especificar su tipo de devolución.
– Jeyekomon
12 de junio de 2019 a las 13:42
Es cierto que solo usando
None
porque la insinuación de tipo no parece lógica porque no es un tipo, a menos que uno sepa que internamenteNone
se interpreta comotype(None)
cual esNoneType
.– estrellado
30 de marzo a las 0:17