Como posso especificar o tipo de função nas minhas dicas de tipo?


136

Eu quero usar dicas de tipo no meu projeto atual do Python 3.5. Minha função deve receber uma função como parâmetro.

Como posso especificar a função de tipo nas minhas dicas de tipo?

import typing

def my_function(name:typing.AnyStr, func: typing.Function) -> None:
    # However, typing.Function does not exist.
    # How can I specify the type function for the parameter `func`?

    # do some processing
    pass

Eu verifiquei o PEP 483 , mas não consegui encontrar uma dica de tipo de função lá.


20
Uma função éCallable
jonrsharpe 15/06

3
python.org/dev/peps/pep-0483/#fundamental-building-blocks , último ponto antes de "poderíamos adicionar".

Respostas:


172

Como @jonrsharpe observou em um comentário, isso pode ser feito com typing.Callable:

from typing import AnyStr, Callable

def my_function(name: AnyStr, func: Callable) -> None:

O problema é que, Callablepor si só, é traduzido para o Callable[..., Any]que significa:

Um chamador pega qualquer número de / tipo de argumentos e retorna um valor de qualquer tipo. Na maioria dos casos, isso não é o que você deseja, pois permitirá que praticamente qualquer função seja aprovada. Você deseja que os parâmetros de função e tipos de retorno também sejam sugeridos.

É por isso que muitos types de typingter sido sobrecarregado para suporte sub-scripting que denota estes tipos extras. Portanto, se, por exemplo, você tivesse uma função sumque recebe dois se intretorna um int:

def sum(a: int, b: int) -> int: return a+b

Sua anotação seria:

Callable[[int, int], int]

ou seja, os parâmetros são subcriptografados na assinatura externa com o tipo de retorno como o segundo elemento na assinatura externa. Em geral:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]

25
esse typingmaterial move a linguagem python inteira um pouco mais.
javadba

1
@ javadba - oh, sim, mas ainda não tenho certeza sobre qual discagem ... A propósito - e quanto Callable[[Arg, Types, Here], ...]a *args, **kwargsargs somente com palavras-chave e args posicionais apenas? Eles não pensaram em chamar convenção nas assinaturas de tipo de chamadas? ;)
Tomasz Gandor

10

Outro ponto interessante a ser observado é que você pode usar a função interna type()para obter o tipo de função interna e usá-la. Então você poderia ter

def f(my_function: type(abs)) -> int:
    return my_function(100)

Ou algo dessa forma


Uma dica de tipo pode ser o que você desejar, mas elas nem sempre foram avaliadas preguiçosamente. Além disso, sua função realmente leva apenas builtin_function_or_methodcomo my_function? Não seria um lambdatrabalho? Uma função definida pelo usuário ou método vinculado?
Tomasz Gandor
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.