Wie erstelle ich ein unveränderliches Wörterbuch in Python?

Ich möchte subclass dict in Python so dass alle Wörterbücher der Unterklasse sind unveränderlich.

Ich verstehe nicht, wie __hash__ die Unveränderlichkeit beeinflusst, denn in meinem Verständnis bedeutet es nur die Gleichheit oder Nichtgleichheit von Objekten!

Also, kann __hash__ verwendet werden, um Unveränderlichkeit zu implementieren? Wie ?

Update :

Ziel ist, dass eine gemeinsame Antwort aus einer API als Dict verfügbar ist, die als globale Variable freigegeben werden muss. Also, das muss intakt sein egal was?

  • Unterklassen int in Python
  • Wie benutzt man die Ellipse-Slicing-Syntax in Python?
  • Wie subclass numpy.`ma.core.masked_array`?
  • Django Multi-Table-Vererbung, wie zu wissen, welche ist die Kind-Klasse eines Modells?
  • Warum werden nicht Pythons Superklasse __init__ Methoden automatisch aufgerufen?
  • Wie man "Superclass-Methoden" in einer Unterklasse "verstecken" kann
  • Unterklassen von Pandas 'Objekt funktionieren anders als Unterklasse eines anderen Objekts?
  • Unterklassen von Python-Tupel mit mehreren __init__-Argumenten
  • 3 Solutions collect form web for “Wie erstelle ich ein unveränderliches Wörterbuch in Python?”

    Also, kann __hash__ verwendet werden, um Unveränderlichkeit zu implementieren?

    Nein, das kann nicht. Das Objekt kann veränderlich gemacht werden (oder nicht), unabhängig davon, was seine __hash__ Methode tut.

    Die Beziehung zwischen unveränderlichen Objekten und __hash__ ist, dass, da ein unveränderliches Objekt nicht verändert werden kann, der von __hash__ Wert __hash__ bleibt. Für veränderliche Gegenstände kann dies sein oder auch nicht der Fall sein (die empfohlene Praxis ist, dass solche Objekte einfach nicht zu Hash).

    Zur weiteren Erörterung siehe Ausgabe 13707: hash() Konstanzperiode klären .

    In Bezug auf die Beziehung zwischen Rutschbarkeit und Veränderlichkeit:

    Um nützlich zu sein, muss eine Hash-Implementierung die folgenden Eigenschaften erfüllen:

    1. Der Hashwert von zwei Objekten, die gleich mit == vergleichen, muss gleich sein.

    2. Der Hash-Wert darf sich im Laufe der Zeit nicht ändern.

    Diese beiden Eigenschaften bedeuten, dass Hash-Klassen keine vergleichbaren Eigenschaften berücksichtigen können, wenn sie Instanzen vergleichen, und durch Kontraktion, dass Klassen, die beim Vergleich von Instanzen veränderliche Eigenschaften berücksichtigen, nicht haltbar sind. Unveränderliche Klassen können ohne irgendwelche Implikationen zum Vergleich gemacht werden.

    Alle eingebauten veränderlichen Typen sind nicht hashable, und alle unveränderlichen eingebauten Typen sind hashable. Dies ist hauptsächlich eine Folge der obigen Beobachtungen.

    Benutzerdefinierte Klassen definieren standardmäßig den Vergleich anhand der Objektidentität und verwenden die id() als Hash. Sie sind veränderlich, aber die veränderlichen Daten werden bei der Vergleichung von Instanzen nicht berücksichtigt, so dass sie hashable gemacht werden können.

    Machen eine Klasse Hashable macht es nicht unveränderlich in etwas magischen Weise. Im Gegenteil, um ein Wörterbuch in einer vernünftigen Weise zu machen, während Sie den ursprünglichen Vergleichsoperator behalten, müssen Sie es zuerst unveränderlich machen.

    Bearbeiten : Bezüglich deines Updates:

    Es gibt mehrere Möglichkeiten, das Äquivalent des globalen unveränderlichen Wörterbuchs zur Verfügung zu stellen:

    1. Verwenden Sie stattdessen eine collections.namedtuple() .

    2. Verwenden Sie eine benutzerdefinierte Klasse mit schreibgeschützten Eigenschaften.

    3. Ich würde normalerweise mit so etwas gehen:

       _my_global_dict = {"a": 42, "b": 7} def request_value(key): return _my_global_dict[key] 

      Durch den führenden Unterstrich stellen Sie klar, dass _my_global_dict ein Implementierungsdetail ist, das nicht von Anwendungscode berührt wird. Beachten Sie, dass dieser Code noch erlauben würde, Wörterbuchwerte zu ändern , wenn es sich um veränderbare Objekte handelt. Sie könnten dieses Problem lösen, indem Sie copy.copy() s oder copy.deepcopy() s der Werte bei Bedarf zurückgeben.

    Fand einen offiziellen Hinweis:

     class imdict(dict): def __hash__(self): return id(self) def _immutable(self, *args, **kws): raise TypeError('object is immutable') __setitem__ = _immutable __delitem__ = _immutable clear = _immutable update = _immutable setdefault = _immutable pop = _immutable popitem = _immutable 

    Namensnennung: http://www.python.org/dev/peps/pep-0351/

    Python ist die beste Programmiersprache der Welt.