À partir de Python sources d'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__
d'attribut.
- Le reste de l'objet
x
est rachetable iff x->ob_type->tp_call != NULL
Desciption de l' 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 les haut- callable
fonction pour déterminer si l'objet donné est remboursable ou non; ou, mieux encore, il vous suffit d'appeler et d'attraper 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 simpliste cache de mise en œuvre:
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 la bibliothèque standard, fichier site.py
, de la définition de haut- exit()
et quit()
fonctions de:
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')