222 votes

Comment puis-je spécifier le type de fonction dans mes indications de type ?

Je souhaite utiliser les indications de type dans mon projet Python 3.5 actuel. Ma fonction doit recevoir une fonction comme paramètre.

Comment puis-je spécifier la fonction de type dans mes indications de type ?

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

J'ai vérifié PEP 483 mais n'a pas pu y trouver d'indication de type de fonction.

31 votes

Une fonction est Callable

3 votes

python.org/dev/peps/pep-0483/#fundamental-building-blocks Dernier point avant "nous pourrions ajouter".

302voto

Jim Points 8793

Comme @jonrsharpe noté dans un commentaire, cela peut être fait avec typing.Callable :

from typing import AnyStr, Callable

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

La question est, Callable en soi, est traduit en Callable[..., Any] ce qui signifie :

Un callable prend tout nombre/type de et renvoie une valeur de n'importe quel type. Dans la plupart des cas, ce n'est pas ce que vous voulez puisque vous autorisez pratiquement n'importe quelle fonction à être passée. Vous voulez que les paramètres de la fonction et les types de retour soient également indiqués.

C'est pourquoi beaucoup types en typing ont été surchargés pour prendre en charge les sous-scripteurs qui désignent ces types supplémentaires. Ainsi, si, par exemple, vous aviez une fonction sum qui prend deux int et renvoie un int :

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

Votre annotation pour cela serait :

Callable[[int, int], int]

c'est-à-dire que les paramètres sont sous-scrits dans l'abonnement externe avec le type de retour comme deuxième élément dans l'abonnement externe. En général :

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

45 votes

Este typing ce qui fait monter d'un cran le langage Python tout entier.

1 votes

@javadba - oh, oui, mais je ne suis toujours pas sûr sur quel cadran... Au fait - qu'en est-il de Callable[[Arg, Types, Here], ...] pour *args , **kwargs les args de mots-clés seulement et les args positionnels seulement ? N'ont-ils pas pensé à la convention d'appel dans les signatures de type pour les appelables ? ;)

1 votes

Selon les docs , typing.Callable semble être en faveur de collections.abc.Callable :

13voto

Hallsville3 Points 109

Un autre point intéressant à noter est que vous pouvez utiliser la fonction incorporée type() pour obtenir le type d'une fonction intégrée et l'utiliser. Ainsi, vous pourriez avoir

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

Ou quelque chose de cette forme

1 votes

Un indice de type peut être ce que vous souhaitez, mais ils n'ont pas toujours été évalués paresseusement. De plus, votre fonction ne prend-elle vraiment que builtin_function_or_method comme my_function ? Est-ce qu'un lambda travail ? Une fonction définie par l'utilisateur ou une méthode liée ?

0 votes

Une façon très intelligente, au moins pour le dépannage ou le brainstorming

1 votes

Non, vous ne pouvez pas, lorsque vous exécutez mypy ce qui donne l'erreur : error: Invalid type comment or annotation note: Suggestion: use type[...] instead of type(...) .

1voto

Jorge Massih Points 23

La solution la plus simple et la plus fantaisiste est la suivante :

def f(my_function: type(lambda x: None)):
    return my_function()

Ceci peut être prouvé de la manière suivante :

def poww(num1, num2):
    return num1**num2

print(type(lambda x: None) == type(poww))

et la sortie sera : True

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X