@mutetella: Ich weiss wie `update()` arbeitet, darum hätte ich ja auch die Reihenfolge umgedreht, damit das gleiche Ergebnis heraus kommt.
Code: Alles auswählen
defaults = {'alignment': '<', 'ellipsis': '…'}
defaults.update(stylesheet.get('defaults', {}))
element = dict(defaults)
element.update(stylesheet['element'])
Mit der Aussage das veränderliche Objekte immer auch „global” vorhanden sind, hast Du *mich* jetzt verwirrt. Das sind sie natürlich nicht, sondern immer nur dort wo man sie auch hin übergeben hat. Und man sollte darauf vertrauen das sie nicht verändert werden solange das nicht klar aus dem Funktions-/Methodennamen oder der Dokumentation hervorgeht wo man das Objekt übergibt.
Veränderliche Objekte müssen natürlich auch zurückgegeben werden. Wenn man das *nie* machen würde, käme man nicht weit, denn solche Objekte würden ja auch lokal in Funktionen neu erzeugt werden können — und dann möchte man sie manchmal auch dem Aufrufer geben. Und man möchte sie sicher auch gerne mal in Datenstrukturen stecken — und da auch wieder heraus holen!
Wenn Du das generell unsauber findest, dann ist Python nicht die richtige Sprache für Dich weil Objekte mit veränderbarem Zustand in der Objektorientierung ziemlich zentral sind, und weil Python so gar nicht dafür bekannt ist dem Programmierer da irgendwelche Hürden in den Weg zu legen. Da wäre eine funktionale Programmiersprache die deutlich mehr Fokus auf unveränderliche Werttypen legt, vielleicht eher Dein Geschmack. Clojure zum Beispiel. Oder eventuell auch Rust.
In Python selbst kannst Du natürlich auch versuchen funktionaler zu Programmieren. Dann würde Deine `setdefault()`-Funktion zum Beispiel ein *neues* Wörterbuch zurück geben und die beiden Argumente unverändert lassen. Das habe ich letztlich ohne Funktion mit meinem `update()`-Beispiel weiter oben gemacht. Das kann man auch in eine (echte) Funktion verpacken:
Code: Alles auswählen
def updated(mapping_a, mapping_b):
result = dict(mapping_a)
result.update(mapping_b)
return result
Und der Beispielcode:
Code: Alles auswählen
defaults = updated(
{'alignment': '<', 'ellipsis': '…'}, stylesheet.get('defaults', {})
)
element = updated(defaults, stylesheet['element'])