Wird das Ändern des __dict__ eines Objekts zum Festlegen seiner Eigenschaften als pythonisch betrachtet?

12

Ich habe eine Klasse, die Objekte aus Zeilen aufbläst, die in einer Datenbank (oder einer anderen Quelle, z. B. MongoDB, einer CSV-Datei usw.) gefunden wurden. Um die Eigenschaften des Objekts festzulegen, wird etwas wie self.__dict__.update(**properties)oder ausgeführt obj.__dict__.update(**properties).

Wird dies als pythonisch angesehen? Ist dies ein gutes Muster, das ich weiterhin verwenden sollte, oder wird dies als schlechte Form angesehen?

Skyler
quelle
1
Ich weiß nicht, ob es Pythonic ist, aber es ist sicherlich üblicher, es in Dunder Init zu tun.
user16764

Antworten:

10

In Python 3.3 wurde ein neuer Typ hinzugefügt, der types.SimpleNamespace()in der Dokumentation folgendermaßen beschrieben wird:

Der Typ entspricht ungefähr dem folgenden Code:

class SimpleNamespace:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
    def __repr__(self):
        keys = sorted(self.__dict__)
        items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
        return "{}({})".format(type(self).__name__, ", ".join(items))

Beachten Sie die __init__Methode des Typs; Sie können keine bessere Bestätigung für die Technik erhalten als die Python-Dokumentation.

Martijn Pieters
quelle
Es SimpleNamespaceunterscheidet sich jedoch von den meisten Typen darin, dass es keine festen Attribute hat.
7
Apropos Python-Dokumentation aus docs.python.org/2/library/stdtypes.html "Ein spezielles Attribut jedes Moduls ist __dict__. Dies ist das Wörterbuch, das die Symboltabelle des Moduls enthält. Wenn Sie dieses Wörterbuch ändern, wird das Symbol des Moduls geändert Tabelle, aber eine direkte Zuordnung zu dem __dict__Attribut ist nicht möglich (Sie können schreiben m.__dict__['a'] = 1, was m.a1 bedeutet, aber nicht writem.__dict__ = {}). Direkte Änderungen __dict__werden nicht empfohlen . "Aus diesem Grund habe ich diese Frage anfangs gestellt.
Skyler
@skyler: beachte, dass nur der Modul-Namespace erwähnt wird . Die globals()Funktion gibt den gleichen Namespace zurück, und es gibt normalerweise bessere Möglichkeiten, Probleme zu lösen, als Globals dynamisch festzulegen, daher die Warnung.
Martijn Pieters