Die Python-Funktion getattr(obj, name, default) liest ein Attribut von einem Objekt dynamisch zur Laufzeit — der Attribut-Name ist ein String, kann also aus einer Variable, einer Konfiguration oder einer Eingabe kommen. Mit dem optionalen default-Parameter wird ein Fallback geliefert, falls das Attribut nicht existiert, statt einen AttributeError auszulösen.
Einleitung
getattr() ist eines der drei zentralen Reflection-Werkzeuge Pythons, gemeinsam mit setattr() und delattr(). Während der normale Point-Zugriff (obj.attr) den Attributnamen zur Schreibzeit kennt, erlaubt getattr(obj, name) den Zugriff über einen String — also über einen Wert, der erst zur Laufzeit feststeht.
Das macht getattr() zur idealen Wahl für Aufgaben wie Plugin-Architekturen, Strategy-Pattern, Konfigurations-Mappings oder beim Bauen von Tools, die fremden Code introspekt-basiert verwenden. Mit dem optionalen default-Argument lassen sich saubere „falls nicht vorhanden"-Defaults definieren — viel knapper als ein try/except AttributeError.
Intern nutzt getattr() denselben Lookup-Mechanismus wie der Point-Zugriff: erst die Instanz-__dict__, dann die Klassenhierarchie, dann __getattr__. Properties, Descriptors und __slots__ werden korrekt mitberücksichtigt.
Syntax
getattr(object, name)
getattr(object, name, default)object Beliebiges Python-Objekt: Instanz, Klasse, Modul.
name Name des Attributs als String.
default (Optional) Wert, der zurückgegeben wird, wenn das Attribut nicht existiert. Ohne diesen Parameter wird ein AttributeError ausgelöst.
Rückgabewert
Den Wert des Attributs obj.name oder den default-Wert. Methoden werden ungebunden zurückgegeben (man kann sie speichern und später aufrufen).
Beispiele
Dynamischer Attributzugriff
class User:
def __init__(self):
self.name = "Michael"
self.alter = 34
u = User()
feld = "name"
print(getattr(u, feld))MichaelMit Default statt AttributeError
u = User()
print(getattr(u, "email", "keine E-Mail"))keine E-MailMethoden referenzieren
text = "Hallo Welt"
method = getattr(text, "upper")
print(method())HALLO WELTPlugin-/Strategy-Pattern
class Renderer:
def render_html(self, data): return f"<p>{data}</p>"
def render_md(self, data): return f"**{data}**"
r = Renderer()
format = "md"
method = getattr(r, f"render_{format}", None)
if method:
print(method("Hallo"))**Hallo**Praktische Beispiele
CLI-Befehle dynamisch dispatchen
class Commands:
def cmd_help(self): print("Hilfe wird angezeigt")
def cmd_list(self): print("Listing der Einträge")
def cmd_clean(self): print("Cache wird geleert")
cli = Commands()
for arg in ["help", "clean", "unknown"]:
handler = getattr(cli, f"cmd_{arg}", None)
if handler:
handler()
else:
print(f"Unbekanntes Kommando: {arg}")Hilfe wird angezeigt
Cache wird geleert
Unbekanntes Kommando: unknownZugriff auf nested Attribute
class Config:
db = type("DB", (), {"host": "localhost", "port": 5432})
def deep_get(obj, path, default=None):
for part in path.split("."):
obj = getattr(obj, part, default)
if obj is default:
return default
return obj
print(deep_get(Config, "db.host"))
print(deep_get(Config, "db.user", "anonymous"))localhost
anonymousLazy Attribute-Initialisierung
class Cache:
def __init__(self):
self._data = None
@property
def data(self):
if getattr(self, "_loaded", False):
return self._data
print("Lade Daten ...")
self._data = [1, 2, 3]
self._loaded = True
return self._data
c = Cache()
print(c.data)
print(c.data) # nicht erneut geladenLade Daten ...
[1, 2, 3]
[1, 2, 3]Praktische Hinweise
obj.attrist schneller alsgetattr(obj, "attr")—getattr()erst nutzen, wenn der Name dynamisch ist.- Default vermeidet
try/except AttributeErrorund ist idiomatisch für „optionale Attribute". - Custom
__getattr__wird nur aufgerufen, wenn der reguläre Lookup fehlschlägt —getattr()triggert es korrekt. - Verwandte Funktionen:
setattr()(setzen),delattr()(löschen),hasattr()(prüfen).