Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 351 – Das Freeze-Protokoll

Autor:
Barry Warsaw <barry at python.org>
Status:
Abgelehnt
Typ:
Standards Track
Erstellt:
14. Apr. 2005
Python-Version:
2.5
Post-History:


Inhaltsverzeichnis

Zusammenfassung

Diese PEP beschreibt ein einfaches Protokoll zum Anfordern einer gefrorenen, unveränderlichen Kopie eines veränderlichen Objekts. Sie definiert auch eine neue integrierte Funktion, die dieses Protokoll verwendet, um eine unveränderliche Kopie für jedes kooperierende Objekt bereitzustellen.

Ablehnungsbescheid

Diese PEP wurde abgelehnt. Eine Begründung finden Sie in diesem Thread auf python-dev.

Begründung

Integrierte Objekte wie Wörterbücher und Mengen akzeptieren nur unveränderliche Objekte als Schlüssel. Das bedeutet, dass veränderliche Objekte wie Listen nicht als Schlüssel für ein Wörterbuch verwendet werden können. Ein Python-Programmierer kann jedoch eine Liste in ein Tupel umwandeln; die beiden Objekte sind ähnlich, aber letzteres ist unveränderlich und kann als Wörterbuchschlüssel verwendet werden.

Es ist denkbar, dass Drittanbieterobjekte ebenfalls ähnliche veränderliche und unveränderliche Gegenstücke haben, und es wäre nützlich, ein standardisiertes Protokoll für die Konvertierung solcher Objekte zu haben.

sets.Set-Objekte stellen ein „Protokoll für die automatische Konvertierung in Unveränderlichkeit“ bereit, damit Sie sets.Sets von sets.Sets erstellen können. PEP 218 hat diese Funktion absichtlich aus den integrierten Mengen entfernt. Diese PEP argumentiert, dass die Funktion immer noch nützlich ist und schlägt einen Standardmechanismus für deren Unterstützung vor.

Vorschlag

Es wird vorgeschlagen, eine neue integrierte Funktion namens freeze() hinzuzufügen.

Wenn freeze() ein unveränderliches Objekt übergeben wird, wie durch hash() auf diesem Objekt bestimmt, das keine TypeError auslöst, dann wird das Objekt direkt zurückgegeben.

Wenn freeze() ein veränderliches Objekt übergeben wird (d. h. hash() dieses Objekts löst eine TypeError aus), ruft freeze() die Methode __freeze__() des Objekts auf, um eine unveränderliche Kopie zu erhalten. Wenn das Objekt keine __freeze__()-Methode hat, wird eine TypeError ausgelöst.

Beispielimplementierungen

Hier ist eine Python-Implementierung der integrierten Funktion freeze()

def freeze(obj):
    try:
        hash(obj)
        return obj
    except TypeError:
        freezer = getattr(obj, '__freeze__', None)
        if freezer:
            return freezer()
        raise TypeError('object is not freezable')

Hier sind einige Codebeispiele, die die beabsichtigten Semantiken zeigen

class xset(set):
    def __freeze__(self):
        return frozenset(self)

class xlist(list):
    def __freeze__(self):
        return tuple(self)

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

class xdict(dict):
    def __freeze__(self):
        return imdict(self)
>>> s = set([1, 2, 3])
>>> {s: 4}
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: set objects are unhashable
>>> t = freeze(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/tmp/python-lWCjBK.py", line 9, in freeze
TypeError: object is not freezable
>>> t = xset(s)
>>> u = freeze(t)
>>> {u: 4}
{frozenset([1, 2, 3]): 4}
>>> x = 'hello'
>>> freeze(x) is x
True
>>> d = xdict(a=7, b=8, c=9)
>>> hash(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: dict objects are unhashable
>>> hash(freeze(d))
-1210776116
>>> {d: 4}
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: dict objects are unhashable
>>> {freeze(d): 4}
{{'a': 7, 'c': 9, 'b': 8}: 4}

Referenzimplementierung

Patch 1335812 liefert die C-Implementierung dieser Funktion. Sie fügt die integrierte Funktion freeze() hinzu, zusammen mit Implementierungen der Methode __freeze__() für Listen und Mengen. Wörterbücher sind in aktuellem Python nicht einfach einzufrieren, daher ist eine Implementierung von dict.__freeze__() noch nicht verfügbar.

Offene Themen

  • Sollen wir ein ähnliches Protokoll zum „Auftauen“ gefrorener Objekte definieren?
  • Sollen Wörterbücher und Mengen ihre veränderlichen Schlüssel automatisch einfrieren?
  • Sollen wir „temporäres Einfrieren“ unterstützen (vielleicht mit einer Methode namens __congeal__()) a la __as_temporarily_immutable__() in sets.Set?
  • Zur Abwärtskompatibilität mit sets.Set, sollen wir __as_immutable__() unterstützen? Oder soll __freeze__() einfach in __as_immutable__() umbenannt werden?

Quelle: https://github.com/python/peps/blob/main/peps/pep-0351.rst

Zuletzt geändert: 2025-09-16 00:19:46 GMT