Seite 1 von 1
Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Montag 23. September 2019, 13:50
von test.py
Hi,
ich möchte erreichen, mehrere alternative Einstellungspresets zu definieren und ein bestimmtes Preset mittels Zuweisung zu selektieren. Im restlichen Programm soll dann mit generischen Bezeichnern gearbeitet werden können, die je nach ausgewählter Einstellung verschiedene Werte annehmen.
Einfaches Beispiel:
Code: Alles auswählen
LAYOUT_BORING = {
"TEXTBOX_PREFIX": "# ",
"TEXTBOX_HEADING": "# " + "=" * 80,
"TEXTBOX_INDENT": " "
}
LAYOUT_FANCY = {
"TEXTBOX_PREFIX": "| ",
"TEXTBOX_HEADING": "| " + "=" * 80,
"TEXTBOX_INDENT": " "
}
LAYOUT = LAYOUT_FANCY
print(LAYOUT["TEXTBOX_HEADING"])
print(LAYOUT["TEXTBOX_PREFIX"] + "Items:")
print(LAYOUT["TEXTBOX_PREFIX"] + LAYOUT["TEXTBOX_INDENT"] + "Item 1")
So weit, so gut. Nun würde ich gerne auch bereits hingeschriebene Einträge in einem Dictionary in diesem auch gleich verwenden können. Dazu habe ich im Netz diese Variante gefunden:
Code: Alles auswählen
class NestedDict(dict):
def __getitem__(self, item):
return dict.__getitem__(self, item) % self
LAYOUT_BORING = NestedDict({
"TEXTBOX_PREFIX" : "# ",
"TEXTBOX_HEADING" : "%(TEXTBOX_PREFIX)s" + "=" * 80,
"TEXTBOX_INDENT" : " "
})
LAYOUT_FANCY = NestedDict({
"TEXTBOX_PREFIX": "| ",
"TEXTBOX_HEADING": "%(TEXTBOX_PREFIX)s" + "=" * 80,
"TEXTBOX_INDENT": " "
})
LAYOUT = LAYOUT_FANCY
print(...)
Jetzt will ich aber meinen eigentlichen Code, der folgt, auch nicht so aufgebläht und unleserlich haben. Schöner wäre es, globale Attribute nutzen zu können. Das könnte ich folgendermaßen erreichen:
Code: Alles auswählen
globals().update(LAYOUT)
print(TEXTBOX_HEADING)
print(TEXTBOX_PREFIX + "Items:")
print(TEXTBOX_PREFIX + TEXTBOX_INDENT + "Item 1")
Das wäre schön, funktioniert aber nicht, weil das Nesting hierdurch kaputtgeht. Wie könnte ich das fixen? Ich finde zu diesem Problem leider nichts wirklich ...
(und falls jemand von euch eine Idee hat, wie ich mein ursprüngliches Problem mit den Presets schöner und eleganter lösen kann, bin ich auch für Vorschläge offen.)
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Montag 23. September 2019, 14:03
von Sirius3
Solche `globals`-Spielereien machen den Code nicht übersichtlicher, sondern undurchsichtiger. Die Zugriffe auf `LAYOUT` finden ja auch nicht überall statt, sondern nur in sehr wenigen Funktionen, mit denen Du dann komplexere Textboxen generieren kannst.
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 15:15
von test.py
Hi,
ob das den Code übersichtlicher macht, war zum einen ja gar nicht die Frage, zum anderen geht es im realen Anwendungsfall nicht nur um Textboxen, sondern um allerlei Dinge, um Text formatiert auszugeben. Die Textbox sollte nur als einfach verständliches Beispiel dienen.

In meinem Fall werden diese Dinge auch ständig verwendet, um Strings die gewünschte Farbe, den gewünschten Abstand, den gewünschten Separator etc. zu geben. Die Variante mit LAYOUT["KEY"] ist da doch sehr sperrig, wenn es zigmal in einer Zeile benutzt werden soll ... gäbe es kein "Problem" damit, hätte ich schließlich nicht in einem Forum gepostet.
LG
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 15:27
von __deets__
Mit globals geht es halt nicht, das ist nunmal ein eingebautes dict, und nicht deine eigene Unterklasse. Und das wird sich jenseits von selbst-komplieren des Interpreters auch nicht aendern lassen. Und was nun so ein Problem an einem immer genutzen Praefix wie zB L ist -
Code: Alles auswählen
from my_layout_definitions import L
def tralala():
print(L.TEXBOX.PREFIX)
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 15:29
von __blackjack__
@test.py: Ob es den Code übersichtlicher macht ist immer Teil der Frage.
Wenn Du nicht ``LAYOUT["TEXTBOX_HEADING"]`` schreiben willst, dann nenn das Wörterbuch halt nicht `LAYOUT` sondern `TEXTBOX` und lass bei den Schlüsseln den "TEXTBOX"-Präfix weg: TEXTBOX["HEADING" ]``. Und man könnte auch Klassen statt Wörterbüchern verwenden: ``TEXTBOX.HEADING`` und wäre bei der gleichen Anzahl von Zeichen wie bei ``TEXTBOX_HEADING``.
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 18:28
von test.py
__deets__ hat geschrieben: Mittwoch 25. September 2019, 15:27
Mit globals geht es halt nicht, das ist nunmal ein eingebautes dict, und nicht deine eigene Unterklasse. Und das wird sich jenseits von selbst-komplieren des Interpreters auch nicht aendern lassen.
Also
ohne das Nesting geht es ja, ich hätte es nur eben gerne
mit Nesting gehabt. Ich dachte, das wird schon iwie gehen ...
__deets__ hat geschrieben: Mittwoch 25. September 2019, 15:27
Und was nun so ein Problem an einem immer genutzen Praefix wie zB L ist -
Code: Alles auswählen
from my_layout_definitions import L
def tralala():
print(L.TEXBOX.PREFIX)
Was muss ich denn tun, um auf diese Weise auf das Dictionary zuzugreifen? Kriege das so nicht reproduziert.
Und einen derart kurzen Bezeichner kann ich nicht nehmen, es muss für andere Leute im Team schon noch sprechend genug sein.
__blackjack__ hat geschrieben: Mittwoch 25. September 2019, 15:29
@test.py: Ob es den Code übersichtlicher macht ist immer Teil der Frage.
Wie meinst du das? Also den mir vorliegenden Code würde es definitiv lesbarer machen. Das muss ich am Ende ja selbst entscheiden, ob ich das wünsche oder nicht, und ich wünsche es.

Wäre halt schön, wenn es da eine elegante Möglichkeit gäbe.
__blackjack__ hat geschrieben: Mittwoch 25. September 2019, 15:29
Wenn Du nicht ``LAYOUT["TEXTBOX_HEADING"]`` schreiben willst, dann nenn das Wörterbuch halt nicht `LAYOUT` sondern `TEXTBOX` und lass bei den Schlüsseln den "TEXTBOX"-Präfix weg: TEXTBOX["HEADING" ]``. Und man könnte auch Klassen statt Wörterbüchern verwenden: ``TEXTBOX.HEADING`` und wäre bei der gleichen Anzahl von Zeichen wie bei ``TEXTBOX_HEADING``.
Eine Config-Klasse wäre evtl. eine Option. Am Ende würde ich die Konfiguration aber gerne aus einer JSON-Datei einlesen, darum blieb ich bisher beim Dictionary, weil es da bereits passende Funktionen gibt. Also bevorzugt wäre ein Dictionary, aber ich überleg mal, ob ich das auch mit Klasse hinkriege.

Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 18:44
von sparrow
Dein Beitrag ist leicht schizophren. Auf der einen Seite willst du keine kurzen Bezeichner, weil andere im "Team" das auch verstehen müssen, gleichzeitig willst du aber krude Dinge tun, die niemand in Python so machen würde.
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 23:16
von __deets__
Wenn die Leute lernen, dass magisch Konstanten entstehen, lernen die auch einen Präfix zu benutzen. Und es geht halt auch nicht anders. Wünsche hin oder her.
Den Zugriff ohne [""] erreichst du mit __getitem__. Aufpassen musst du natürlich das die genestelten Dicts wieder von deiner Klasse sind. Das gilt aber ja schon jetzt.
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Mittwoch 25. September 2019, 23:22
von __blackjack__
Für Attributzugriff auf (verschachtelte) Wörterbücher verwende ich in der Regel `addict.Dict`.
Re: Keys aus nested Dictionary in globale Attruibute umwandeln
Verfasst: Donnerstag 26. September 2019, 07:13
von Sirius3
Und das ganze mit einer JSON-Konfigurationsdatei:
Code: Alles auswählen
with open('layout.json', encoding="utf8") as data:
layout = json.load(data, object_hook=addict.Dict)
textbox = layout.textbox