Was ist ein "Callable"?

310

Jetzt, da klar ist, was eine Metaklasse ist , gibt es ein zugehöriges Konzept, das ich ständig verwende, ohne zu wissen, was es wirklich bedeutet.

Ich nehme an, jeder hat einmal einen Fehler mit Klammern gemacht, was zu einer Ausnahme "Objekt ist nicht aufrufbar" führte. Was mehr ist, verwenden __init__und __new__sich fragen, wofür dieses blutige __call__verwendet werden kann.

Können Sie mir einige Erklärungen geben, einschließlich Beispiele mit der magischen Methode?

e-satis
quelle

Antworten:

308

Ein Callable ist alles, was aufgerufen werden kann.

Der eingebaute in aufrufbar (PyCallable_Check in objects.c) prüft , ob das Argument entweder:

  • eine Instanz einer Klasse mit einer __call__Methode oder
  • ist von einem Typ, der ein Nicht-Null- tp_call (c struct) -Mitglied hat, das eine andere Aufrufbarkeit anzeigt (z. B. in Funktionen, Methoden usw.).

Die genannte Methode __call__ist ( laut Dokumentation )

Wird aufgerufen, wenn die Instanz als Funktion aufgerufen wird

Beispiel

class Foo:
  def __call__(self):
    print 'called'

foo_instance = Foo()
foo_instance() #this is calling the __call__ method
Florian Bösch
quelle
6
Beachten Sie, dass das eingebaute Callable in Python 3.0 entfernt wird, um nach Aufrufen zu
suchen
13
@Eli: Hmm das klingt nach einem sehr schlechten Zug. callablesagt Ihnen tatsächlich, ob etwas aufrufbar ist oder nicht, während Sie nach suchen, __call__sagt Ihnen nichts; Wenn ein Objekt True obereitstellt __getattribute__oder zurückgeben kann __getattr__, hasattr(o, '__call__')kann oes dennoch nicht aufgerufen werden, da Python überspringt __getattribute__und __getattr__aufruft. Der einzige wirkliche Weg, um zu überprüfen, ob etwas aufrufbar ist, ist somit EAFP.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
49
@Longpoke: Nur für den Datensatz lesen Sie bitte die Dokumentation callable()in Python 3.x : " Diese Funktion wurde zuerst in Python 3.0 entfernt und dann in Python 3.2 zurückgebracht. "
Tadeck
Es scheint, dass in Python 3.8 nur das Vorhandensein von tp_callüberprüft wird. Siehe Implementierung von PyCallable_Check , es sind 3 Zeilen.
Michele Piccolini
84

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:

  1. Wenn ein Objekt eine Instanz einer Klasse ist, kann es aufgerufen werden, wenn es ein __call__Attribut hat.
  2. Else das Objekt xist aufrufbar iff x->ob_type->tp_call != NULL

Beschreibung des tp_callFeldes :

ternaryfunc tp_callEin 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 callableFunktion verwenden, um zu bestimmen, ob ein bestimmtes Objekt aufrufbar ist oder nicht. oder besser noch anrufen und TypeErrorspäter fangen . callablewird 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')
jfs
quelle
10
Ich finde das Beispiel für die Call - Methode sehr missleading , weil sie es mit einem Rezept für das Caching und Dekorateure mischt, die nichts zum Verständnis hinzufügen Anruf
Florian Bösch
3
JF Sebastian hilft es nicht, weitere Beispiele zu stapeln, die Sie von einem anderen Ort kopiert und eingefügt haben, die nicht minimal sind.
Florian Bösch
20
@JF Sebastian: Es ist BS, dass mehr lebensechte Beispiele besser sind. Ich könnte Ihnen lebensechten Code zeigen, der Sie als Beispiel zum Weinen bringen würde. Einfache Beispiele funktionieren auch und sie veranschaulichen etwas besser, weil sie nicht ablenken.
Florian Bösch
5
Sie erklären, was ein Callable ist, haben aber ein Beispiel gegeben, wie Callable-Objekte zum Definieren eines Dekorators verwendet werden. Ich weiß, dass es eine typische Verwendung von callable ist, aber dies kann Leser verwirren, die nur wissen möchten, was callable ist und wie man callable verwendet . Ich würde die Antwort von @Florian Bösch vorziehen.
KFL
2
@ Kay: Ich mag auch die Antwort von @Florian Bösch (in der aktuellen Form). Übrigens ist ein Dekorateur keine typische Verwendung eines "Callable". Die typischsten „Callables“ sind Funktionen / Methoden wie def f(): ...und Klassenobjekte wie das class C: ...heißt f, ''.strip, len, und Calle sind aufrufbar. Instanzen, die eine __call__()Methode in ihrer Klasse haben, sind relativ selten.
JFS
37

Ein aufrufbares Objekt ist ein Objekt, mit dem Sie runde Klammern () verwenden und schließlich einige Parameter übergeben können, genau wie Funktionen.

Jedes Mal, wenn Sie eine Funktion definieren, erstellt Python ein aufrufbares Objekt. Beispiel: Sie können die Funktion func folgendermaßen definieren (es ist dasselbe):

class a(object):
    def __call__(self, *args):
        print 'Hello'

func = a()

# or ... 
def func(*args):
    print 'Hello'

Sie könnten diese Methode anstelle von Methoden wie doit oder run verwenden . Ich denke, es ist nur klarer, obj () zu sehen als obj.doit ()

Andrea Ambu
quelle
37

Lassen Sie mich rückwärts erklären:

Bedenken Sie...

foo()

... als syntaktischer Zucker für:

foo.__call__()

Wo fookann jedes Objekt , das reagiert auf sein __call__. Wenn ich ein Objekt sage, meine ich es: integrierte Typen, Ihre eigenen Klassen und deren Instanzen.

Bei integrierten Typen beim Schreiben:

int('10')
unicode(10)

Sie tun im Wesentlichen:

int.__call__('10')
unicode.__call__(10)

Das ist auch der Grund, warum Sie es foo = new intin Python nicht haben : Sie lassen das Klassenobjekt einfach eine Instanz davon zurückgeben __call__. Die Art und Weise, wie Python dies löst, ist meiner Meinung nach sehr elegant.

hcalves
quelle
Du machst im Wesentlichen type(int).__call__(int, '10')und type(unicode).__call__(unicode, '10'). Dunders werden immer in ihrer Klasse aufgerufen, nicht über die Instanz. Und sie gehen auch nie durch die Metaklasse. In den meisten Fällen ist das nur ein Trottel, aber manchmal ist es wichtig.
Mad Physicist
11

Ein Callable ist ein Objekt mit der __call__Methode. Dies bedeutet, dass Sie aufrufbare Funktionen fälschen oder nette Dinge wie Partial Function Application ausführen können, bei denen Sie eine Funktion übernehmen und etwas hinzufügen, das sie verbessert oder einige der Parameter ausfüllt, und so etwas zurückgeben, das wiederum aufgerufen werden kann ( in funktionalen Programmierkreisen als Currying bezeichnet) ).

Bei bestimmten typografischen Fehlern versucht der Interpreter, etwas aufzurufen, das Sie nicht beabsichtigt haben, z. B. eine Zeichenfolge. Dies kann zu Fehlern führen, wenn der Interpreter versucht, eine nicht aufrufbare Anwendung auszuführen. Sie können dies in einem Python-Interpreter sehen, indem Sie so etwas wie das folgende Transkript ausführen.

[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
>>> 
ConcernedOfTunbridgeWells
quelle
9

__call__ macht jedes Objekt als Funktion aufrufbar.

In diesem Beispiel wird 8 ausgegeben:

class Adder(object):
  def __init__(self, val):
    self.val = val

  def __call__(self, val):
    return self.val + val

func = Adder(5)
print func(3)
MvdD
quelle
7

Ganz einfach, ein "aufrufbar" ist etwas, das wie eine Methode aufgerufen werden kann. Die integrierte Funktion "callable ()" zeigt an, ob etwas aufrufbar zu sein scheint, ebenso wie die Suche nach einer Call- Eigenschaft. Funktionen können ebenso wie Klassen aufgerufen werden, Klasseninstanzen können aufgerufen werden. Mehr dazu hier und hier .

Joe Skora
quelle
5

In Python ist ein Callable ein Objekt, dessen Typ eine __call__Methode hat:

>>> 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

So einfach ist das :)

Dies kann natürlich überladen werden:

>>> class Foo(object):
...  def __call__(self):
...   return 42
... 
>>> f = Foo()
>>> f()
42
Armin Ronacher
quelle
3

Zu überprüfen, ob die Funktion oder Methode der Klasse aufrufbar ist oder nicht, bedeutet, dass wir diese Funktion aufrufen können.

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
Ravi Singh
quelle
1
Sind Sie sicher, callable(obj.__init___)dass Sie keinen zusätzlichen Unterstrich haben (wie in AttributeError)? Wenn nicht, sind Sie sicher, dass die Antwort nicht Truefür diese ist?
Mad Physicist
2

Es ist etwas, nach dem Sie "(args)" setzen können und erwarten, dass es funktioniert. Ein Callable ist normalerweise eine Methode oder eine Klasse. Methoden werden aufgerufen, Klassen instanziiert.

Kevin Conner
quelle
2

Callables implementieren die __call__spezielle Methode, sodass jedes Objekt mit einer solchen Methode aufgerufen werden kann.

Cobie
quelle
Eine von Ihnen definierte Instanz kann __call__nicht aufgerufen werden, wenn die Klasse eine solche Methode nicht definiert.
Mad Physicist
2

Aufrufbare ist eine Art oder eine Klasse von „Build-In - Funktion oder Methode“ mit einer Methode Aufruf

>>> type(callable)
<class 'builtin_function_or_method'>
>>>

Beispiel: print ist ein aufrufbares Objekt. Mit einer integrierten Funktion __call__ Wenn Sie die Druckfunktion aufrufen , erstellt Python ein Objekt vom Typ print und ruft seine Methode __call__ auf, wobei die Parameter gegebenenfalls übergeben werden.

>>> type(print)
<class 'builtin_function_or_method'>
>>> print.__call__(10)
10
>>> print(10)
10
>>>

Danke dir. Grüße, Maris

Maris
quelle
1
Einige der Informationen hier sind falsch. Beispiel: "Wenn Sie die printFunktion aufrufen , erstellt Python ein Objekt vom Typ print und ruft dessen Methode auf. __call__" Python erstellt kein Druckobjekt. Es nennt nur etwas Äquivalentes zu type(print).__call__(print, *args, **kwargs). Und der erste Satz macht nicht viel Sinn. Sie scheinen ein aufrufbares Objekt zu verwirren und die Funktion "aufrufbar" zu machen.
Mad Physicist