Maintenant que c'est clair c'est quoi une métaclasse , il y a un concept associé que j'utilise tout le temps sans savoir ce que ça veut vraiment dire.
Je suppose que tout le monde a commis une fois une erreur avec une parenthèse, ce qui a entraîné une exception "l'objet n'est pas appelable". De plus, utiliser __init__
et __new__
conduit à se demander à quoi sert ce sanglant __call__
.
Pourriez-vous me donner quelques explications, y compris des exemples avec la méthode magique?
Un appelable est tout ce qui peut être appelé.
Le intégré appelable (PyCallable_Check dans objects.c) vérifie si l'argument est l'un des suivants:
__call__
ouLa méthode nommée __call__
est ( selon la documentation )
Appelé lorsque l'instance est "" appelée "en tant que fonction
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
Depuis les sources de Python object.c :
_/* Test whether an object can be called */
int
PyCallable_Check(PyObject *x)
{
if (x == NULL)
return 0;
if (PyInstance_Check(x)) {
PyObject *call = PyObject_GetAttrString(x, "__call__");
if (call == NULL) {
PyErr_Clear();
return 0;
}
/* Could test recursively but don't, for fear of endless
recursion if some joker sets self.__call__ = self */
Py_DECREF(call);
return 1;
}
else {
return x->ob_type->tp_call != NULL;
}
}
_
Ça dit:
__call__
_.x
est appelable si et seulement si _x->ob_type->tp_call != NULL
_Description de champ _tp_call
_ :
_
ternaryfunc tp_call
_ Un pointeur facultatif sur une fonction qui implémente l'appel de l'objet. Cela devrait être NULL si l'objet n'est pas appelable. La signature est la même que pour PyObject_Call (). Ce champ est hérité par sous-types.
Vous pouvez toujours utiliser la fonction intégrée callable
pour déterminer si un objet donné est appelable ou non; ou mieux encore, appelez-le et attrapez TypeError
plus tard. callable
est supprimé dans Python 3.0 et 3.1, utilisez callable = lambda o: hasattr(o, '__call__')
ou isinstance(o, collections.Callable)
.
Exemple, une implémentation simpliste du cache:
_class Cached:
def __init__(self, function):
self.function = function
self.cache = {}
def __call__(self, *args):
try: return self.cache[args]
except KeyError:
ret = self.cache[args] = self.function(*args)
return ret
_
Usage:
_@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
_
Exemple tiré de la bibliothèque standard, fichier site.py
, définition des fonctions exit()
et quit()
intégrées:
_class Quitter(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return 'Use %s() or %s to exit' % (self.name, eof)
def __call__(self, code=None):
# Shells like IDLE catch the SystemExit, but listen when their
# stdin wrapper is closed.
try:
sys.stdin.close()
except:
pass
raise SystemExit(code)
__builtin__.quit = Quitter('quit')
__builtin__.exit = Quitter('exit')
_
Un callable est un objet qui vous permet d'utiliser des parenthèses arrondies () et éventuellement de transmettre certains paramètres, tout comme les fonctions.
Chaque fois que vous définissez une fonction, python crée un objet appelable. Par exemple, vous pourriez définir la fonction func de cette manière (c'est la même chose):
class a(object):
def __call__(self, *args):
print 'Hello'
func = a()
# or ...
def func(*args):
print 'Hello'
Vous pouvez utiliser cette méthode à la place de méthodes telles que doit ou run, je pense que c'est plus clair de voir obj () qu'obj.doit ()
Permettez-moi d'expliquer à l'envers:
Considère ceci...
foo()
... en sucre syntaxique pour:
foo.__call__()
Où foo
peut être n'importe quel objet qui répond à __call__
. Quand je dis un 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:
int('10')
unicode(10)
Vous faites essentiellement:
int.__call__('10')
unicode.__call__(10)
C'est aussi pourquoi vous n'avez pas foo = new int
en Python: vous faites simplement en sorte que l'objet de classe retourne une instance de celui-ci sur __call__
. La façon dont Python résout ce problème est très élégante à mon avis.
Un appelable est un objet qui a la méthode __call__
. Cela signifie que vous pouvez simuler des fonctions appelables ou faire des choses ordonnées comme Application de fonction partielle où vous prenez une fonction et ajoutez quelque chose qui l'améliore ou remplit certains des paramètres, retournant quelque chose qui peut être appelé à son tour ( connu sous le nom de Currying dans les cercles de programmation fonctionnels).
Certaines erreurs typographiques peuvent amener l’interprète à appeler quelque chose que vous n’avez pas voulu, tel que (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ète python en effectuant quelque chose comme la transcription ci-dessous.
[nigel@k9 ~]$ python
Python 2.5 (r25:51908, Nov 6 2007, 15:55:44)
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'aaa'() # <== Here we attempt to call a string.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>>
Tout simplement, un "appelable" 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 recherche d'une propriété call . Les fonctions sont appelables comme les classes, les instances de classe peuvent être appelées. Voir plus à ce sujet ici et ici .
__call__
permet à tout objet d'être appelable en tant que fonction.
Cet exemple affichera 8:
class Adder(object):
def __init__(self, val):
self.val = val
def __call__(self, val):
return self.val + val
func = Adder(5)
print func(3)
Dans Python, un appelable est un objet dont le type a une méthode __call__
:
>>> class Foo:
... pass
...
>>> class Bar(object):
... pass
...
>>> type(Foo).__call__(Foo)
<__main__.Foo instance at 0x711440>
>>> type(Bar).__call__(Bar)
<__main__.Bar object at 0x712110>
>>> def foo(bar):
... return bar
...
>>> type(foo).__call__(foo, 42)
42
Aussi simple que cela :)
Ceci peut bien sûr être surchargé:
>>> class Foo(object):
... def __call__(self):
... return 42
...
>>> f = Foo()
>>> f()
42
Vérifier que la fonction ou la méthode de la classe est appelable ou non, cela signifie que nous pouvons appeler cette fonction.
Class A:
def __init__(self,val):
self.val = val
def bar(self):
print "bar"
obj = A()
callable(obj.bar)
True
callable(obj.__init___)
False
def foo(): return "s"
callable(foo)
True
callable(foo())
False
C'est quelque chose que vous pouvez mettre "(args)" après et vous attendre à ce que cela fonctionne. Un callable est généralement une méthode ou une classe. Les méthodes sont appelées, les classes sont instanciées.
callables implémente la méthode spéciale __call__
afin qu'un objet doté d'une telle méthode puisse être appelé.
Callable est un type ou une classe de "Fonction ou méthode intégrée" avec une méthode call
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
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 l'invoque sa méthode _ CALL _ en passant les paramètres éventuels.
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
Je vous remercie. Cordialement, Maris