Qu'est-ce qu'un" appelable " en Python?
maintenant qu'il est clair ce qu'est une métaclasse , il y a un concept associé que j'utilise tout le temps sans savoir ce qu'il signifie vraiment.
je suppose que tout le monde a fait une erreur avec une parenthèse, résultant en une exception" objet n'est pas appelable". De plus, l'utilisation de __init__
et __new__
conduit à se demander à quoi ce sanglant __call__
peut être utilisé.
Pourriez-vous me donner quelques explications, y compris des exemples avec la méthode magique ?
12 réponses
un appelant est tout ce qui peut être appelé.
Le built-in callable (PyCallable_Check dans les objets.c) vérifie si l'argument est:
- une instance d'une classe avec un __appel__ méthode
- est d'un type qui a un non null tp_call (struct c) le membre qui indique callability autrement (par exemple comme dans les fonctions, les méthodes, etc.)
La méthode nommée __appel__ ( , selon la documentation )
appelé lorsque l'instance est "appelé" comme une fonction
exemple
class Foo:
def __call__(self):
print 'called'
foo_instance = Foo()
foo_instance() #this is calling the __call__ method
De Python sources objet.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;
}
}
Il dit:
- Si un objet est une instance d'une classe, alors il est appelable iff il a
__call__
attribut. - Sinon l'objet
x
est appelable iffx->ob_type->tp_call != NULL
Desciption de tp_call
champ :
ternaryfunc tp_call
facultatif pointeur vers une fonction qui implémente l'appel de l'objet. Cela devrait être La valeur NULL si l'objet n'est pas appelable. La signature est la même que pour PyObject_Call(). Ce champ est héritées par les 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, il suffit de l'appeler et de saisir TypeError
plus tard. callable
est supprimé en Python 3.0 et 3.1, utilisez callable = lambda o: hasattr(o, '__call__')
ou isinstance(o, collections.Callable)
.
exemple, une implémentation de cache simpliste:
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
Utilisation:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
exemple de 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 la parenthèse ronde ( ) et éventuellement passer quelques 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 cette façon (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 au lieu de méthodes comme doit ou exécuter , je je pense que c'est juste plus clair de voir obj() que obj.doit ()
Laissez-moi vous expliquer en arrière:
considérez ceci...
foo()
... comme sucre syntactique pour:
foo.__call__()
Où foo
peut être n'importe quel objet qui répond à __call__
. Quand je dis n'importe quel objet, je le pense: des types intégrés, vos propres classes et leurs instances.
Dans le cas de types intégrés, lorsque vous écrivez:
int('10')
unicode(10)
vous faites essentiellement:
int.__call__('10')
unicode.__call__(10)
C'est aussi la raison pour laquelle vous n'avez pas foo = new int
en Python: vous faites simplement que l'objet de classe retourne une instance de celui-ci sur __call__
. La façon dont Python résout cela est très élégant à mon avis.
un appelable est un objet qui a la méthode __call__
. Cela signifie que vous pouvez simuler des fonctions appelant ou faire des choses soignées comme application de fonction partielle où vous prenez une fonction et ajouter quelque chose qui l'améliore ou remplit certains des paramètres, retournant quelque chose qui peut être appelé à son tour (connu comme Currying dans les cercles de programmation fonctionnelle).
certaines erreurs typographiques auront le interprète essayant d'appeler quelque chose que vous n'aviez pas l'intention, comme (par exemple) une chaîne de caractères. 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.
[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 "callable" est quelque chose qui peut être appelé comme une méthode. La fonction intégrée "callable () "vous indiquera si quelque chose semble être callable, tout comme la vérification d'une propriété call . Les fonctions sont appelables comme le sont les classes, les instances de classe peuvent être appelables. En savoir plus sur ce ici et ici .
__call__
rend n'importe quel objet callable comme une fonction.
cet exemple produira 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)
en Python un callable 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:)
cela bien sûr peut être surchargé:
>>> class Foo(object):
... def __call__(self):
... return 42
...
>>> f = Foo()
>>> f()
42
C'est quelque chose que vous pouvez mettre "(args)" après et espérer qu'il fonctionne. Un appelable est habituellement une méthode ou une classe. Les méthodes sont appelées, les classes sont instanciées.
pour vérifier la fonction ou la méthode de 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
Callable est un type ou une classe de "Build-in function or Method" avec une méthode appel
>>> type(callable)
<class 'builtin_function_or_method'>
>>>
exemple: imprimer est un objet appelable. Avec une fonction intégrée _ _ call _ _ _ Lorsque vous invoquez la fonction print , Python crée un objet de type print et invoque sa méthode _ _ _ call _ _ en passant les paramètres si tout.
>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>
Merci. Égard, Maris
callables implémenter la méthode spéciale __call__
donc tout objet avec une telle méthode est callable.