Die Python-Funktion issubclass(cls, classinfo) prüft, ob cls eine direkte oder indirekte Subklasse von classinfo ist. Eine Klasse gilt dabei auch als ihre eigene Subklasse — issubclass(int, int) ergibt True. Wie bei isinstance() lässt sich classinfo als Tupel mehrerer Klassen übergeben.
Einleitung
Während isinstance() mit Instanzen arbeitet, prüft issubclass() direkt Klassen-Beziehungen. Sie ist das richtige Werkzeug, wenn man eine Klasse als Wert hat (etwa als Argument einer Factory-Funktion oder im Plugin-Mechanismus) und prüfen will, ob sie eine bestimmte API erfüllt.
Wie isinstance() versteht issubclass() auch Abstract Base Classes (ABCs) und damit „virtuelle" Subklassen, die per register() an eine ABC angehängt wurden — ein mächtiges Pattern für strukturelle Typisierung.
Syntax
issubclass(cls, classinfo)cls Die zu prüfende Klasse. Muss eine Klasse sein — bei einer Instanz wirft die Funktion TypeError.
classinfo Eine Klasse oder ein Tupel von Klassen.
Rückgabewert
True, wenn cls eine Subklasse einer in classinfo genannten Klasse ist (oder die Klasse selbst). Sonst False.
Beispiele
Standard-Vererbung
class Animal: pass
class Dog(Animal): pass
class Poodle(Dog): pass
print(issubclass(Poodle, Dog))
print(issubclass(Poodle, Animal))
print(issubclass(Dog, Poodle)) # umgekehrt: False
print(issubclass(Animal, Animal)) # Klasse ist eigene SubklasseTrue
True
False
TrueMit Tupel von Klassen
class A: pass
class B: pass
class C(B): pass
print(issubclass(C, (A, B))) # B ist Vorfahr → True
print(issubclass(C, (A,))) # nicht in A-Hierarchie → FalseTrue
FalseBuiltins
print(issubclass(bool, int)) # bool erbt von int
print(issubclass(int, object)) # alles erbt von object
print(issubclass(list, tuple)) # nicht verwandtTrue
True
FalsePraktische Beispiele
Plugin-Registrierung mit Subklassen-Check
class Plugin:
name = "Basis-Plugin"
class Logger(Plugin):
name = "Logger-Plugin"
class NotAPlugin: pass
def register(cls):
if not issubclass(cls, Plugin):
raise TypeError(f"{cls.__name__} ist kein Plugin")
print(f"Registriert: {cls.name}")
register(Logger)
try:
register(NotAPlugin)
except TypeError as e:
print(e)Registriert: Logger-Plugin
NotAPlugin ist kein PluginVirtuelle Subklassen mit ABC
from abc import ABC
class JsonSerializable(ABC):
pass
class MyData:
def to_json(self): return "{}"
# MyData hat keine Vererbungsbeziehung — wird virtuell registriert
JsonSerializable.register(MyData)
print(issubclass(MyData, JsonSerializable))TrueFiltern aller Subklassen
class Shape: pass
class Circle(Shape): pass
class Square(Shape): pass
class Car: pass
classes = [Circle, Square, Car, Shape]
shapes = [c for c in classes if issubclass(c, Shape)]
print([c.__name__ for c in shapes])['Circle', 'Square', 'Shape']Praktische Hinweise
- Klasse, nicht Instanz: Eine Instanz als erstes Argument wirft
TypeError. Bei Instanzenisinstance()nutzen. issubclass(C, C) is True— Reflexivität gehört zur Subklassen-Definition.- Virtuelle Subklassen via
ABC.register(...)ermöglichen Strukturtyp-Prüfungen ohne explizite Vererbung. - Verwandte API:
cls.__mro__zeigt die komplette Method Resolution Order,cls.__subclasses__()listet die direkt abgeleiteten Klassen.