As outras respostas fizeram um bom trabalho ao explicar a digitação de patos e a resposta simples de tzot :
Python não possui variáveis, como outras linguagens em que variáveis têm um tipo e um valor; possui nomes apontando para objetos, que conhecem seu tipo.
No entanto , uma coisa interessante mudou desde 2010 (quando a pergunta foi feita pela primeira vez), a saber, a implementação do PEP 3107 (implementada no Python 3). Agora você pode realmente especificar o tipo de um parâmetro e o tipo do tipo de retorno de uma função como esta:
def pick(l: list, index: int) -> int:
return l[index]
Podemos ver aqui que são pick
necessários 2 parâmetros, uma lista l
e um número inteiro index
. Também deve retornar um número inteiro.
Então, aqui está implícito que l
há uma lista de números inteiros que podemos ver sem muito esforço, mas para funções mais complexas pode ser um pouco confuso quanto ao que a lista deve conter. Também queremos que o valor padrão index
seja 0. Para resolver isso, você pode optar por escrever pick
assim:
def pick(l: "list of ints", index: int = 0) -> int:
return l[index]
Observe que agora colocamos uma string como o tipo de l
, que é sintaticamente permitido, mas não é bom para analisar programaticamente (que voltaremos mais tarde).
É importante observar que o Python não aumentará TypeError
se você passar um float index
, a razão para isso é um dos principais pontos na filosofia de design do Python: "Todos nós somos adultos concordantes aqui" , o que significa que você deve esteja ciente do que você pode passar para uma função e do que não pode. Se você realmente deseja escrever código que lança TypeErrors, pode usar a isinstance
função para verificar se o argumento passado é do tipo apropriado ou uma subclasse dele como esta:
def pick(l: list, index: int = 0) -> int:
if not isinstance(l, list):
raise TypeError
return l[index]
Mais sobre por que você raramente deve fazer isso e o que deve fazer é discutido na próxima seção e nos comentários.
O PEP 3107 não apenas melhora a legibilidade do código, mas também possui vários casos de uso adequados sobre os quais você pode ler aqui .
A anotação de tipo recebeu muito mais atenção no Python 3.5 com a introdução do PEP 484, que introduz um módulo padrão para dicas de tipo.
Essas dicas de tipo vieram do verificador de tipos mypy ( GitHub ), que agora é compatível com PEP 484 .
O módulo de digitação vem com uma coleção bastante abrangente de dicas de tipo, incluindo:
List
, Tuple
, Set
, Map
- para list
, tuple
, set
e map
respectivamente.
Iterable
- útil para geradores.
Any
- quando poderia ser qualquer coisa.
Union
- quando poderia ser qualquer coisa dentro de um conjunto especificado de tipos, em oposição a Any
.
Optional
- quando pode ser Nenhum. Taquigrafia para Union[T, None]
.
TypeVar
- usado com genéricos.
Callable
- usado principalmente para funções, mas pode ser usado para outros callables.
Essas são as dicas de tipo mais comuns. Uma lista completa pode ser encontrada na documentação do módulo de digitação .
Aqui está o exemplo antigo usando os métodos de anotação introduzidos no módulo de digitação:
from typing import List
def pick(l: List[int], index: int) -> int:
return l[index]
Um recurso poderoso é o Callable
que permite digitar métodos de anotação que assumem uma função como argumento. Por exemplo:
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))
O exemplo acima pode se tornar mais preciso com o uso de em TypeVar
vez de Any
, mas isso foi deixado como um exercício para o leitor, pois acredito que já preenchi minha resposta com muitas informações sobre os maravilhosos novos recursos habilitados pela dica de tipo.
Anteriormente, quando um código Python documentado com, por exemplo, Sphinx, algumas das funcionalidades acima podiam ser obtidas escrevendo-se documentos formatados da seguinte forma:
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 você pode ver, isso requer várias linhas extras (o número exato depende de quão explícito você deseja ser e de como formata sua string de documento). Mas agora deve ficar claro para você como o PEP 3107 fornece uma alternativa que é, de várias maneiras (superior?) Superior. Isso é especialmente verdadeiro em combinação com o PEP 484 , que, como vimos, fornece um módulo padrão que define uma sintaxe para essas dicas / anotações de tipo que podem ser usadas de tal maneira que sejam inequívocas e precisas, mas flexíveis. combinação poderosa.
Na minha opinião pessoal, esse é um dos maiores recursos do Python de todos os tempos. Mal posso esperar para as pessoas começarem a aproveitar o poder disso. Desculpe pela resposta longa, mas é isso que acontece quando fico animado.
Um exemplo de código Python que usa fortemente dicas de tipo pode ser encontrado aqui .