Las otras respuestas han hecho un buen trabajo al explicar la escritura de los patos y la respuesta simple de tzot :
Python no tiene variables, como otros lenguajes donde las variables tienen un tipo y un valor; tiene nombres que apuntan a objetos, que conocen su tipo.
Sin embargo , una cosa interesante ha cambiado desde 2010 (cuando se hizo la pregunta por primera vez), a saber, la implementación de PEP 3107 (implementado en Python 3). Ahora puede especificar el tipo de parámetro y el tipo de retorno de una función como esta:
def pick(l: list, index: int) -> int:
return l[index]
Podemos ver aquí que pick
toma 2 parámetros, una lista l
y un número entero index
. También debería devolver un número entero.
Entonces, aquí está implícito que l
es una lista de enteros que podemos ver sin mucho esfuerzo, pero para funciones más complejas puede ser un poco confuso lo que debe contener la lista. También queremos que el valor predeterminado index
sea 0. Para resolver esto, puede optar por escribir pick
así:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Tenga en cuenta que ahora ponemos una cadena como el tipo de l
, que está sintácticamente permitido, pero no es bueno para el análisis mediante programación (que volveremos más adelante).
Es importante tener en cuenta que Python no generará un aumento TypeError
si pasa un flotador index
, la razón de esto es uno de los puntos principales en la filosofía de diseño de Python: "Aquí todos aceptamos adultos" , lo que significa que se espera que usted tenga en cuenta lo que puede pasar a una función y lo que no puede. Si realmente desea escribir código que arroje TypeErrors, puede usar la isinstance
función para verificar que el argumento pasado sea del tipo apropiado o una subclase de este tipo:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
En la siguiente sección y en los comentarios se habla más sobre por qué rara vez se debe hacer esto y qué se debe hacer en su lugar.
PEP 3107 no solo mejora la legibilidad del código, sino que también tiene varios casos de uso adecuados que puede leer aquí .
La anotación de tipo recibió mucha más atención en Python 3.5 con la introducción de PEP 484, que presenta un módulo estándar para sugerencias de tipo.
Estas sugerencias de tipo provienen del verificador de tipo mypy ( GitHub ), que ahora cumple con PEP 484 .
Con el módulo de mecanografía viene con una colección bastante completa de sugerencias de tipos, que incluyen:
List
, Tuple
, Set
, Map
- para list
, tuple
, set
y map
respectivamente.
Iterable
- útil para generadores.
Any
- Cuando podría ser cualquier cosa.
Union
- cuando podría ser cualquier cosa dentro de un conjunto específico de tipos, a diferencia de Any
.
Optional
- Cuando podría ser Ninguno. Taquigrafía para Union[T, None]
.
TypeVar
- Utilizado con genéricos.
Callable
- se usa principalmente para funciones, pero podría usarse para otras llamadas.
Estas son las sugerencias de tipo más comunes. Se puede encontrar una lista completa en la documentación del módulo de escritura .
Aquí está el viejo ejemplo usando los métodos de anotación introducidos en el módulo de escritura:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
Una característica poderosa es la Callable
que le permite escribir métodos de anotación que toman una función como argumento. Por ejemplo:
from typing import Callable, Any, Iterable
def imap(f: Callable[[Any], Any], l: Iterable[Any]) -> List[Any]:
"""An immediate version of map, don't pass it any infinite iterables!"""
return list(map(f, l))
El ejemplo anterior podría volverse más preciso con el uso de en TypeVar
lugar de Any
, pero esto se ha dejado como un ejercicio para el lector, ya que creo que ya llené mi respuesta con demasiada información sobre las nuevas características maravillosas habilitadas por las sugerencias de tipo.
Anteriormente, cuando se documentaba un código de Python con, por ejemplo, Sphinx, algunas de las funciones anteriores se podían obtener escribiendo cadenas de documentos con el siguiente formato:
def pick(l, index):
"""
:param l: list of integers
:type l: list
:param index: index at which to pick an integer from *l*
:type index: int
:returns: integer at *index* in *l*
:rtype: int
"""
return l[index]
Como puede ver, esto requiere varias líneas adicionales (el número exacto depende de cuán explícito quiera ser y de cómo formatee su cadena de documentación). Pero ahora debería estar claro para usted cómo PEP 3107 proporciona una alternativa que es superior en muchos (¿todos?). Esto es especialmente cierto en combinación con PEP 484 que, como hemos visto, proporciona un módulo estándar que define una sintaxis para este tipo de sugerencias / anotaciones que se pueden usar de tal manera que sea inequívoca y precisa pero flexible, lo que hace que Potente combinación.
En mi opinión personal, esta es una de las mejores características de Python. No puedo esperar a que la gente empiece a aprovechar su poder. Perdón por la respuesta larga, pero esto es lo que sucede cuando me emociono.
Aquí se puede encontrar un ejemplo de código de Python que usa muchas sugerencias de tipo .