Aus Pythons Quellen 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;
}
}
Es sagt:
- Wenn ein Objekt eine Instanz einer Klasse ist, kann es aufgerufen werden, wenn es ein
__call__
Attribut hat.
- Else das Objekt
x
ist aufrufbar iff x->ob_type->tp_call != NULL
Beschreibung des tp_call
Feldes :
ternaryfunc tp_call
Ein optionaler Zeiger auf eine Funktion, die das Aufrufen des Objekts implementiert. Dies sollte NULL sein, wenn das Objekt nicht aufrufbar ist. Die Signatur ist dieselbe wie für PyObject_Call (). Dieses Feld wird von Untertypen geerbt.
Sie können jederzeit die integrierte callable
Funktion verwenden, um zu bestimmen, ob ein bestimmtes Objekt aufrufbar ist oder nicht. oder besser noch anrufen und TypeError
später fangen . callable
wird in Python 3.0 und 3.1 entfernt, verwenden Sie callable = lambda o: hasattr(o, '__call__')
oder isinstance(o, collections.Callable)
.
Beispiel eine vereinfachte Cache-Implementierung:
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
Verwendungszweck:
@Cached
def ack(x, y):
return ack(x-1, ack(x, y-1)) if x*y else (x + y + 1)
Beispiel aus Standardbibliothek, Datei site.py
, Definition der integrierten Funktionen exit()
und quit()
Funktionen:
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')