Die Python-Funktion type() hat zwei sehr unterschiedliche Aufrufmodi: Mit einem Argument liefert sie den Typ eines Objekts (type(42)<class 'int'>). Mit drei Argumenten erzeugt sie zur Laufzeit eine neue Klassetype(name, bases, dict). In dieser Doppelrolle steckt die ganze Macht von Pythons Metaklassen-System: Klassen sind selbst Objekte vom Typ type.

Einleitung

Die einstellige Form type(obj) ist die häufigste — sie liefert die Klasse, von der obj eine Instanz ist. Sie unterscheidet sich von isinstance() in einem wichtigen Punkt: type() ignoriert Vererbung. type(True) == int ist False, weil True eine Instanz von bool ist (auch wenn bool von int erbt). Für korrekte Typprüfungen ist daher fast immer isinstance() die richtige Wahl — nur in seltenen Fällen, in denen man die exakte Klasse braucht (kein Subtyp), nimmt man type().

Die dreistellige Form type(name, bases, dict) ist Metaklassen-Magie. Sie ist das, was Python intern beim class-Keyword aufruft. Damit lassen sich Klassen dynamisch zur Laufzeit erzeugen — nützlich für Plugin-Systeme, ORM-Mapper und DSLs.

Syntax

Python Syntax
type(object)                # → Typ des Objekts
type(name, bases, dict)     # → neue Klasse
Parameter
object

Beliebiges Python-Objekt.

name

Name der neuen Klasse als String — wird zu __name__.

bases

Tupel der Basisklassen (mindestens (object,)).

dict

Dictionary mit den Klassen-Attributen und -Methoden.

Rückgabewert

  • Einstellig: Die Klasse, deren Instanz das Objekt ist.
  • Dreistellig: Eine neue Klasse (vom Typ type).

Beispiele

Typ eines Objekts ermitteln

type() liefert die direkte Klasse — ohne Vererbungs-Berücksichtigung:

Python Beispiel
print(type(42))
print(type("hi"))
print(type([1, 2]))
print(type(None))
print(type(lambda: None))
Output
<class 'int'>
<class 'str'>
<class 'list'>
<class 'NoneType'>
<class 'function'>

type() vs isinstance()

type() ist exakt, isinstance() respektiert die Vererbung. Für Typprüfungen fast immer isinstance() nutzen:

Python Beispiel
x = True
print(type(x) is int)         # False — bool ist nicht exakt int
print(type(x) is bool)         # True
print(isinstance(x, int))      # True — bool erbt von int
Output
False
True
True

Klasse zur Laufzeit erzeugen

Mit der dreistelligen Form lässt sich eine vollständige Klasse aus Strings und Dictionaries bauen — das macht Frameworks wie SQLAlchemy oder Django ORM intern:

Python Beispiel
def greet(self):
    return f"Hello, I'm {self.name}"

Person = type("Person", (object,), {"name": "Alice", "greet": greet})

p = Person()
print(p.greet())
print(type(p).__name__)
Output
Hello, I'm Alice
Person

Praktische Beispiele

Klassen-basierter Dispatch

Ein simpler Type-basierter Dispatch, wo isinstance() nicht ausreichen würde — z. B. wenn Subklassen explizit unterschieden werden sollen:

Python Beispiel
def describe(value):
    handlers = {
        int:  lambda v: f"Ganzzahl: {v}",
        float: lambda v: f"Float: {v:.2f}",
        str:  lambda v: f"Text: {v!r}",
        list: lambda v: f"Liste mit {len(v)} Elementen",
    }
    handler = handlers.get(type(value), lambda v: f"Anderer Typ: {type(v).__name__}")
    return handler(value)

for v in [42, 3.14, "hi", [1, 2, 3], {"a": 1}]:
    print(describe(v))
Output
Ganzzahl: 42
Float: 3.14
Text: 'hi'
Liste mit 3 Elementen
Anderer Typ: dict

Typname als String für Logs

type(obj).__name__ ist die Standardform, um den Typnamen für Fehlermeldungen oder Logs zu bekommen:

Python Beispiel
def expect(value, expected):
    if not isinstance(value, expected):
        raise TypeError(
            f"Erwartet {expected.__name__}, "
            f"bekommen {type(value).__name__}: {value!r}"
        )

try:
    expect("42", int)
except TypeError as e:
    print(e)
Output
Erwartet int, bekommen str: '42'

Enum-ähnliche Konstanten dynamisch generieren

Mit type() und einem Dict lassen sich Hilfsklassen aus Konfigurationen automatisch erzeugen:

Python Beispiel
colors = {"RED": "#ff0000", "GREEN": "#00ff00", "BLUE": "#0000ff"}
Color = type("Color", (object,), colors)
print(Color.RED)
print(Color.BLUE)
Output
#ff0000
#0000ff

Praktische Hinweise

  • Für Typprüfungen: isinstance() bevorzugen — type(x) is Cls nur für exakte Übereinstimmung ohne Subtypen.
  • type(obj).__name__ ist die Standardform für lesbare Typnamen in Fehlermeldungen.
  • Klassen sind selbst Objekte vom Typ typetype(int)<class 'type'>. Das ist die Basis für Metaklassen.
  • Metaklassen werden über class Foo(metaclass=Meta): definiert — fortgeschrittene Anpassung der Klassenerstellung.
  • Verwandte Funktionen: isinstance(), issubclass(), dir(), vars(), inspect.getmro().
/ Weiter

Zurück zu Builtin Functions

Zur Übersicht