navigation Navigation


Inhaltsverzeichnis

callable()


In Python entscheidet die eingebaute Funktion callable(), ob sich ein Objekt wie eine Funktion aufrufen lässt. Dieser Einstieg klärt, was Aufrufbarkeit genau bedeutet, welche Objekttypen darunterfallen (Funktionen, Klassen, Instanzen mit __call__) und wie sich callable() im Alltag nutzen lässt, um APIs abzusichern, Plugins dynamisch zu laden oder flexible Schnittstellen zu gestalten. Außerdem zeigt der Artikel typische Stolpersteine und Best Practices für lesbaren, robusten Code.

Inhaltsverzeichnis

    Einführung

    Die Funktion callable() ist eine eingebaute Python-Funktion die seit Python 2.0 existiert und in Python 3 fortgeführt wurde. Sie dient der Überprüfung, ob ein Objekt aufrufbar (callable) ist. Also, ob es wie eine Funktion verwendet werden kann.

    In Python ist nicht jedes Objekt aufrufbar. Während Funktionen, Methoden und Klassen aufgerufen werden können, sind beispielsweise einfache Datentypen wie Strings, Zahlen oder Listen nicht aufrufbar. Die Funktion callable() löst das Problem der Typ-Überprüfung, bevor man versucht, ein Objekt aufzurufen. Dies verhindert TypeError Exceptions und ermöglicht defensivere Programmierung.

    Beispiel
    x = 42
    x()
    TypeError: 'int' object is not callable

    Wie wir an diesem Beispiel sehen, können wir natürlich ein Objekt vom Typ int nicht aufrufen.

    Mit callable() können wir im Vorfeld prüfen.

    Beispiel
    x = 42
    if callable(x):
        x()
    else:
        print("x ist nicht aufrufbar")
    x ist nicht aufrufbar

    Syntax

    Syntax
    callable(object, /)

    Der Schrägstrich / in der Signatur zeigt an, dass es sich um einen positional-only Parameter handelt. Das bedeutet, der Parameter muss potentionall übergeben werden und kann nicht als Keyword-Argument verwendet werden.

    Gültige Verwendung

    Gültig
    callable(my_function)

    Ungültig

    Syntax
    callable(object=my_function) # TypeError

    Parameter

    object

    Das zu überprüfende Objekt, bei dem festgestellt werden soll, ob es aufrufbar ist


    Rückgabewert

    • True: Das Objekt ist aufrufbar. Hat eine __call__() Methode oder ist eine Funktion/Klasse
    • False: Das Objekt ist nicht aufrufbar

    Wichtig Die Funktion callable() gibt True zurück, wenn das Objekt potentiell aufrufbar ist. Dies garantiert nicht, dass der Aufruf erfolgreich sein wird, da der Aufruf selbst noch fehlschlagen könnte (z.B. durch falsche Argumente).

    Die __call__() Methode

    Ein Objekt in Python ist aufrufbar, wenn:

    1. Es eine Funktion, Methode oder Klasse ist, ODER
    2. Seine Klasse die spezielle Methode __call__() implementiert

    Hier ein Beispiel.

    Beispiel
    class MyCallable:
        def __call__(self, x):
            return x * 2
    
    
    obj = MyCallable()
    
    print(callable(obj))
    print(obj(5))
    True
    10

    In diesem Beispiel ist obj eine Instanz der Klasse MyCallable, aber durch die __call__() Methode wird die Instanz selbst aufrufbar.

    Klassen und Instanzen

    Es ist wichtig zwischen Klassen und deren Instanzen in bezuf auf die Aufrufbarkeit zu unterscheiden.

    Eine Klasse in Python ist immer callable (aufrufbar), um Instanzen dieser Klasse zu erzeugen.

    Dabei ist die Instanz standardmäßig nicht aufrufbar.

    Beispiel
    class MyClass:
        pass
    
    print(callable(MyClass))
    
    instance = MyClass()
    print(callable(instance))
    True
    False

    Eine Instanz ist nur aufrufbar, wenn die __call__() Methode definiert ist.

    Das machen wir nun im nächsten Beispiel.

    Beispiel
    class MyCallableClass:
        def __call__(self):
            return "Ich wurde aufgerufen"
    
    print(callable(MyCallableClass))
    
    instance = MyCallableClass()
    print(callable(instance))
    
    # Rufen wir die Instanz auf und geben das Ergebnis aus
    print(instance())
    True
    True
    Ich wurde aufgerufen

    Praktische Beispiele

    Überprüfung von Funktionen

    Funktionen - egal ob selbst definiert oder eingebaut - sind immer aufrufbar. Einfache Datentypen wie Strings hingegen nicht.

    Beispiel
    def greet(name):
        return f"Hallo, {name}"
    
    print(callable(greet))
    
    text = "Hallo"
    print(callable(text))
    
    print(callable(print))
    print(callable(len))
    True
    False
    True
    True

    Callback-Funktionen validieren

    Ein häufiger Anwendungsfall ist die Validierung von Callback-Funktionen in APIs oder Event-Handler-Systemen.

    Beispiel
    class EventHandler:
        def __init__(self):
            self.callbacks = []
    
        def register_callback(self, callback):
            if not callable(callback):
                raise TypeError(f"Callback muss aufrufbar sein, erhalten: {type(callback)}")
    
            self.callbacks.append(callback)
    
        def trigger(self):
            for callback in self.callbacks:
                callback()
    
    
    handler = EventHandler()
    
    def my_callback():
        print("Event wurde ausgelöst")
    
    handler.register_callback(my_callback)
    handler.trigger()
    
    try:
        handler.register_callback("nicht aufrufbar")
    except TypeError as e:
        print(f"Fehler: {e}")
    
    Event wurde ausgelöst
    Fehler: Callback muss aufrufbar sein, erhalten: <class 'str'>

    Der EventHandler verwendet callable(), um sicherzustellen, dass nur aufrufbare Objekte als Callbacks registriert werden.

    Callable-Objekte als Funktionsersatz

    Callable-Objekte können Zustand speichern, was bei normalen Funktionen nicht möglich ist (ohne globale Variablen oder nonlocal).

    Beispiel
    class Counter:
        
        def __init__(self):
            self.count = 0
    
        def __call__(self):
            self.count += 1
            return f"Ich wurde {self.count} mal aufgerufen"
    
    
    counter = Counter()
    print(callable(counter))
    
    print(counter()) # Ich wurde 1 mal aufgerufen
    print(counter()) # Ich wurde 2 mal aufgerufen
    print(counter()) # Ich wurde 3 mal aufgerufen
    True
    Ich wurde 1 mal aufgerufen
    Ich wurde 2 mal aufgerufen
    Ich wurde 3 mal aufgerufen

    Die Klasse Counter implementiert die Methode __call__(), sodass Instanzen wie Funktionen verwendet werden können. Im Gegensatz zu Funktionen können sie aber Zustand (hier count) zwischen Aufrufen speichern. Das kann in manchen Situation sehr nützlich sein.

    Dekoratoren und Callable

    Dekorierte Funktionen bleiben aufrufbar, da der Dekorator eine neue aufrufbare Funktion (den Wrapper) zurückgibt.

    Beispiel
    def my_decorator(func):
        def wrapper(*args, **kwargs):
            print("Vor dem Funktionsaufruf")
            result = func(*args, **kwargs)
            print("Nach dem Funktionsaufruf")
    
            return result
        
        return wrapper
    
    
    @my_decorator
    def say_hello(name):
        print(f"Hallo {name}")
    
    
    print(callable(say_hello)) # True
    say_hello("Python")
    True
    Vor dem Funktionsaufruf
    Hallo Python
    Nach dem Funktionsaufruf