Maintenant que c'est clair ce qu'est une métaclasse , il y a un concept associé que j'utilise tout le temps sans savoir ce que cela signifie vraiment.
Je suppose que tout le monde a fait une fois une erreur entre parenthèses, ce qui a entraîné une exception "l'objet n'est pas appelable". De plus, utiliser __init__
et __new__
amener à se demander à quoi __call__
peut servir ce sanglant .
Pourriez-vous me donner quelques explications, y compris des exemples avec la méthode magique?
Réponses:
Un appelable est tout ce qui peut être appelé.
Le haut- appelable (PyCallable_Check en objects.C) vérifie si l'argument est soit:
__call__
méthode ouLa méthode nommée
__call__
est ( selon la documentation )Exemple
la source
callable
vous indique réellement si quelque chose est appelable ou non, tandis que la vérification__call__
ne vous dit rien; Si un objeto
fournit__getattribute__
ou__getattr__
,hasattr(o, '__call__')
peut retourner vrai, maiso
ne sera pas encore appelable parce que Python ignore__getattribute__
et__getattr__
pour les appels. Le seul véritable moyen qui reste pour vérifier si quelque chose est appelable est donc EAFP.callable()
Python 3.x : " Cette fonction a d'abord été supprimée en Python 3.0 puis ramenée en Python 3.2. ".tp_call
est vérifiée. Voir l'implémentation de PyCallable_Check , c'est 3 lignes.Depuis les sources de Python object.c :
Ça dit:
__call__
attribut.x
peut être appelé six->ob_type->tp_call != NULL
Description du
tp_call
champ :Vous pouvez toujours utiliser la
callable
fonction intégrée pour déterminer si un objet donné peut être appelé ou non; ou mieux encore appelez-le et attrapezTypeError
plus tard.callable
est supprimé dans Python 3.0 et 3.1, utilisezcallable = lambda o: hasattr(o, '__call__')
ouisinstance(o, collections.Callable)
.Exemple, une implémentation de cache simpliste:
Usage:
Exemple de bibliothèque standard, fichier
site.py
, définition de fonction intégréeexit()
etquit()
fonctions:la source
def f(): ...
et des objets de classe tels que parclass C: ...
exemple,f
,''.strip
,len
etC
tous sont appelable. Les instances qui ont une__call__()
méthode dans leur classe sont relativement rares.Un callable est un objet qui vous permet d'utiliser des parenthèses rondes () et éventuellement de passer certains paramètres, tout comme les fonctions.
Chaque fois que vous définissez une fonction, python crée un objet appelable. Par exemple, vous pouvez définir la fonction func de ces façons (c'est la même chose):
Vous pouvez utiliser cette méthode au lieu de méthodes comme doit ou run , je pense qu'il est plus clair de voir obj () que obj.doit ()
la source
Permettez-moi d'expliquer à l'envers:
Considère ceci...
... comme sucre syntaxique pour:
Où
foo
peut être n'importe quel objet qui répond__call__
. Quand je dis n'importe quel objet, je le pense: les types intégrés, vos propres classes et leurs instances.Dans le cas des types intégrés, lorsque vous écrivez:
Vous faites essentiellement:
C'est aussi pourquoi vous n'en avez pas
foo = new int
en Python: vous faites juste en sorte que l'objet classe en retourne une instance__call__
. La façon dont Python résout cela est très élégante à mon avis.la source
type(int).__call__(int, '10')
ettype(unicode).__call__(unicode, '10')
. Les dunders sont toujours appelés sur leur classe, pas via l'instance. Et ils ne passent jamais par la métaclasse non plus. Dans la plupart des cas, ce n'est qu'un coup de pouce, mais cela compte parfois.Un Callable est un objet qui a la
__call__
méthode. Cela signifie que vous pouvez simuler des fonctions appelables ou faire des choses intéressantes comme l'application de fonction partielle où vous prenez une fonction et ajoutez quelque chose qui l'améliore ou remplit certains des paramètres, renvoyant quelque chose qui peut être appelé à son tour (connu sous le nom de Currying dans les cercles de programmation fonctionnelle ).Certaines erreurs typographiques auront l'interpréteur tentant d'appeler quelque chose que vous ne vouliez pas, comme (par exemple) une chaîne. Cela peut produire des erreurs lorsque l'interpréteur tente d'exécuter une application non appelable. Vous pouvez voir cela se produire dans un interpréteur python en faisant quelque chose comme la transcription ci-dessous.
la source
__call__
rend tout objet appelable en tant que fonction.Cet exemple affichera 8:
la source
Tout simplement, un "callable" est quelque chose qui peut être appelé comme une méthode. La fonction intégrée "callable ()" vous dira si quelque chose semble être appelable, tout comme la vérification d'une propriété d' appel . Les fonctions sont appelables tout comme les classes, les instances de classe peuvent être appelables. En savoir plus ici et ici .
la source
En Python, un appelable est un objet dont le type a une
__call__
méthode:Aussi simple que cela :)
Bien sûr, cela peut être surchargé:
la source
Pour vérifier que la fonction ou la méthode de la classe est appelable ou non, cela signifie que nous pouvons appeler cette fonction.
la source
callable(obj.__init___)
ne pas avoir de soulignement supplémentaire (comme dans AttributeError)? Si ce n'est pas le cas, êtes-vous sûr que la réponse n'est pasTrue
pour celle-là?C'est quelque chose que vous pouvez mettre "(args)" après et vous attendre à ce que cela fonctionne. Un appelable est généralement une méthode ou une classe. Les méthodes sont appelées, les classes sont instanciées.
la source
callables implémentent la
__call__
méthode spéciale de sorte que tout objet avec une telle méthode est appelable.la source
__call__
ne sera pas appelable si la classe ne définit pas une telle méthode.Callable est un type ou une classe de "fonction ou méthode intégrée" avec un appel de méthode
Exemple: print est un objet appelable. Avec une fonction intégrée __call__ Lorsque vous appelez la fonction print , Python crée un objet de type print et invoque sa méthode __call__ en passant les paramètres éventuels.
Je vous remercie. Cordialement, Maris
la source
print
fonction, Python crée un objet de type print et invoque sa méthode__call__
". Python ne crée pas d'objet d'impression. Cela appelle simplement quelque chose d'équivalenttype(print).__call__(print, *args, **kwargs)
. Et la première phrase n'a pas beaucoup de sens. Vous semblez confondre un objet appelable et "appelable" la fonction.