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 Klasse — type(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
type(object) # → Typ des Objekts
type(name, bases, dict) # → neue Klasseobject 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:
print(type(42))
print(type("hi"))
print(type([1, 2]))
print(type(None))
print(type(lambda: None))<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:
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 intFalse
True
TrueKlasse 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:
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__)Hello, I'm Alice
PersonPraktische Beispiele
Klassen-basierter Dispatch
Ein simpler Type-basierter Dispatch, wo isinstance() nicht ausreichen würde — z. B. wenn Subklassen explizit unterschieden werden sollen:
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))Ganzzahl: 42
Float: 3.14
Text: 'hi'
Liste mit 3 Elementen
Anderer Typ: dictTypname als String für Logs
type(obj).__name__ ist die Standardform, um den Typnamen für Fehlermeldungen oder Logs zu bekommen:
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)Erwartet int, bekommen str: '42'Enum-ähnliche Konstanten dynamisch generieren
Mit type() und einem Dict lassen sich Hilfsklassen aus Konfigurationen automatisch erzeugen:
colors = {"RED": "#ff0000", "GREEN": "#00ff00", "BLUE": "#0000ff"}
Color = type("Color", (object,), colors)
print(Color.RED)
print(Color.BLUE)#ff0000
#0000ffPraktische Hinweise
- Für Typprüfungen:
isinstance()bevorzugen —type(x) is Clsnur für exakte Übereinstimmung ohne Subtypen. type(obj).__name__ist die Standardform für lesbare Typnamen in Fehlermeldungen.- Klassen sind selbst Objekte vom Typ
type—type(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().