La réponse acceptée était, au moment où elle a été proposée, considérée comme correcte. Or, il s'avère s'avère, il y a aucun substitut para callable()
qui est de retour dans Python 3.2 : Plus précisément, callable()
vérifie le tp_call
de l'objet en question testé. Il n'y a pas d'équivalent en Python. La plupart des tests proposés sont corrects la plupart du temps :
>>> class Spam(object):
... def __call__(self):
... return 'OK'
>>> can_o_spam = Spam()
>>> can_o_spam()
'OK'
>>> callable(can_o_spam)
True
>>> hasattr(can_o_spam, '__call__')
True
>>> import collections
>>> isinstance(can_o_spam, collections.Callable)
True
Nous pouvons faire une entorse à cette règle en supprimant l'option __call__
de la classe. Et pour rendre les choses encore plus excitantes, ajoutez un faux __call__
à l'instance !
>>> del Spam.__call__
>>> can_o_spam.__call__ = lambda *args: 'OK?'
Remarquez que ce n'est pas vraiment appelable :
>>> can_o_spam()
Traceback (most recent call last):
...
TypeError: 'Spam' object is not callable
callable()
renvoie le résultat correct :
>>> callable(can_o_spam)
False
Mais hasattr
es mauvais :
>>> hasattr(can_o_spam, '__call__')
True
can_o_spam
possède cet attribut après tout ; il n'est simplement pas utilisé lors de l'appel de l'instance.
Encore plus subtile, isinstance()
se trompe également :
>>> isinstance(can_o_spam, collections.Callable)
True
Parce que nous avons utilisé ce contrôle plus tôt et avons ensuite supprimé la méthode, abc.ABCMeta
met en cache le résultat. On peut soutenir qu'il s'agit d'un bogue dans abc.ABCMeta
. Cela dit, il n'y a vraiment aucun moyen possible pourrait produisent un résultat plus précis que le résultat qu'en utilisant callable()
lui-même, puisque le typeobject->tp_call
n'est pas accessible d'une autre manière.
Il suffit d'utiliser callable()
45 votes
Je suis déprimée par le nombre de réponses qui contournent le problème en cherchant des appelez attribut ou fonction appelable... Une façon propre est de type(a) == types.functionType comme suggéré par @ryan
48 votes
La bonne façon de vérifier les propriétés des objets de type canard est de leur demander s'ils font coin-coin, et non de voir s'ils rentrent dans un récipient de la taille d'un canard. L'approche "comparer directement" donnera une mauvaise réponse pour de nombreuses fonctions, comme les buildins.
3 votes
@JohnFeminella Bien que je sois d'accord avec vous sur le principe. Le PO n'a pas demandé si elle était appelable, juste si c'était une fonction. On pourrait peut-être faire valoir qu'il avait besoin d'une distinction entre, par exemple, les fonctions et les classes ?
4 votes
En ce qui me concerne, je suis venu ici parce que je voulais utiliser
insepct.getsource
sur une variété d'objets, et il n'est pas important de savoir si l'objet peut être appelé, mais s'il s'agit de quelque chose qui donne une "fonction" à l'utilisateur.type(obj)
. Puisque Google m'a conduit ici, je dirais que le commentaire d'AsTeR était la réponse la plus utile (pour moi). Il y a beaucoup d'autres endroits sur l'internet que les gens peuvent découvrir.__call__
ocallable
.7 votes
@AsTeR C'est types.FunctionType, avec un F majuscule.
0 votes
@BenMares Je ne peux plus éditer, mais merci de l'avoir remarqué !
0 votes
@AsTeR Yeep clean way mais ça dépend un peu de la personne qui lit sur internet, son choix :) content que Ryan en parle.
0 votes
Utilisez
inspect.isfunction(object)
qui est présent dans le module d'inspection.