Beherrsche das schwache Ref-Modul in Python

Das schwache Ref-Modul ist ein praktisches und sehr leistungsfähiges Modul. Vielleicht wird kein Modul in Bezug auf das Gleichgewicht zwischen Praktikabilität und Namenserkennung so schlecht behandelt wie dieses Modul. In diesem Artikel werde ich Ihnen zeigen, wie nützlich das schwache Ref-Modul ist.

Problem

Angenommen, Sie haben eine große Anzahl von Objekten mit Identitätsinformationen (oder eindeutigen Hash-Informationen). Ein Wörterbuch für die Objektverwaltung wird erstellt, damit eine große Anzahl von Objekten mithilfe der ID als Schlüssel durchsucht werden kann.

class Member:
    def __init__(self, id, name):
        self.id = id
        self.name = name

#Verwalten Sie Objekte mit einem ID-basierten Wörterbuch
members_dict = {
    x.id: x for x in [
        Member(1, "tim"),
        Member(2, "matthew"),
        Member(3, "Jack"),
        # ...
    ]
}

members_dict[1].name
>>> 'tim'

Hier gab es eine Aufforderung, nach "Name" anstatt nur nach "ID" zu suchen. Erstellen wir also ein Wörterbuch mit dem Namen als Schlüssel. (Hier ist der Einfachheit halber "Name" auch eine eindeutige Information ohne Vervielfältigung.)

#Erstellen Sie ein Wörterbuch mit dem Namen als Schlüssel
names_dict = {x.name: x for x in members_dict.values()}

names_dict["tim"].id
>>> 1

Da sich das Mitglied "tim" hier zurückgezogen hat, wurden die Daten gelöscht.

# ID:Löschen Sie die Zeitdaten 1
del members_dict[1]

Es ist wünschenswert, dass die Objektdaten von "tim" durch GC (Garbage Collection) gesammelt und der Speicher freigegeben wird. Aber die Realität ist nicht.

Das Objekt wird durch das im Namen einer Suchtabelle hinzugefügte names_dict referenziert, und das tim-Objekt wird vom GC nicht erfasst und bleibt im Speicher vorhanden.

# names_GC leckt ohne Freigabe, da das Diktat noch Referenzen enthält!
names_dict['tim']
>>> <__main__.Member at 0x1744e889ba8>

Wenn Sie das Erstellen und Löschen von Mitgliedern wiederholen, wird der Speicher nicht freigegeben und sammelt sich an. Daher müssen Sie sowohl "names_dict" als auch "member_dict" gleichzeitig verwalten. Wenn die Arten von Suchtabellen zunehmen, nimmt die Anzahl der gleichzeitig verwalteten Wörterbücher zu, was ein Sumpf ist.

Wenn Sie eine einfache Datenstruktur wie dieses Beispiel haben, können Sie etwas mit einem objektorientierten Design tun.

Wenn es um eine komplizierte Datenstruktur geht, in der Objekte aufeinander verweisen, ist ein Referenzzähler erforderlich, um zu bestimmen, ob das Objekt lebt oder tot ist, und der philosophische Code zum Implementieren einer GC-ähnlichen Sache in der Sprache, in der der GC aufgeführt ist. Abgeschlossen....

Das schwache Ref-Modul kann Ihnen in dieser Situation helfen. Ersetzen Sie einfach names_dict durch schwachref.WeakValuDictionary und es wird das Problem lösen.

from weakref import WeakValueDictionary

names_dict = WeakValueDictionary(
    {_.name: _ for _ in members_dict.values()}
)

names_dict['tim'].id
>>> 1

# ID:Löschen Sie die Zeitdaten 1
del members_dict[1]

names_dict['tim']
>>> KeyError: 'tim'

WeakValuDictionary ist ein wörterbuchähnliches Objekt, dessen Wert eine schwache Referenz ist. Schwache Referenzen sind Referenzen, die die Wiederherstellung von GC nicht beeinträchtigen und automatisch aus dem Wörterbuch gelöscht werden, wenn außer "WeakValuDictionary" keine stärkeren Referenzen vorhanden sind.

Es gibt viele Situationen, in denen Sie mithilfe einer schnellen Cache- / Nachschlagetabelle auf eine große Anzahl von Objekten zugreifen möchten, um die Leistung zu verbessern. In solchen Zeiten kann das "Weak Valu Dictionary" als wesentlicher Bestandteil bezeichnet werden.

Natürlich gibt es auch ein Weak Key Dictionary

Wenn es ein "WeakValuDictionary" gibt, gibt es natürlich auch ein "WeakKeyDictionary", dessen Schlüssel eine schwache Referenz ist.

Das WeakKeyDictionary kann auch verwendet werden, um Referenzen zu speichern und auf die verwiesen wird.

from weakref import WeakKeyDictionary


class Member:
    def __init__(self, name, friend=None):
        self.name = name
        self._friend_dict = WeakKeyDictionary()
        self._referenced_dict = WeakKeyDictionary()
        if friend:
            self._friend_dict[friend] = None
            friend._referenced_dict[self] = None

    def referenced(self):
        referenced = list(self._referenced_dict.keys())
        return referenced[0] if referenced else None

    def friend(self):
        friends = list(self._friend_dict.keys())
        return friends[0] if friends else None

    def __str__(self):
        friend = self.friend()
        refer = self.referenced()
        return "{}: referenced={} friend={}".format(
            self.name,
            refer.name if refer else None,
            friend.name if friend else None
        )


tim = Member("tim")
matthew = Member("matthew", friend=tim)
jack = Member("jack", friend=matthew)

print(tim)
print(matthew)
print(jack)
# output:
#
# tim: referenced='matthew' friend='None'
# matthew: referenced='jack' friend='tim'
# jack: referenced='None' friend='matthew'

del matthew

print(tim)
print(jack)
# output:
#
# tim: referenced='None' friend='None'
# jack: referenced='None' friend='None'

Ich habe es als Wörterbuch verwendet, das die Referenzen und Referenzen anderer Objekte automatisch aktualisiert. Sie können sehen, dass das Wörterbuch automatisch aktualisiert wird, indem Sie das Objekt löschen.

Referenz

Nachwort

Das "softref" -Modul ist ein sehr leistungsfähiges Modul, obwohl es einfach genug ist, dass nur zwei Wörterbuchobjekte, "WeakValuDictionary" und "WeakKeyDictionary", ausreichen. Je nach Gerät gibt es wahrscheinlich viele andere Verwendungszwecke.

Es ist ein sehr unauffälliges Modul, daher denke ich, dass es für Leute, die es nicht kennen, sehr hilfreich ist. Wenn Sie eine andere effektive Verwendung finden, schreiben Sie diese bitte in den Artikel.

Recommended Posts

Beherrsche das schwache Ref-Modul in Python
Installieren Sie das Python-Modul in einem beliebigen Verzeichnis
Finde Fehler in Python
Über das Python-Modul venv
[Python] Ruft die Liste der im Modul definierten Klassen ab
Abrufen der arXiv-API in Python
[Python] Anmelden Ihres eigenen Moduls
Python im Browser: Brythons Empfehlung
Klicken Sie in Python auf die Sesami-API
Holen Sie sich den Desktop-Pfad in Python
Legen Sie das Modul in die Pepper-App
Holen Sie sich den Skriptpfad in Python
Im Python-Befehl zeigt Python auf Python3.8
Implementieren Sie das Singleton-Muster in Python
Den Typ mit Python beherrschen? (Wann ist eine Typprüfung durchzuführen?)
Klicken Sie auf die Web-API in Python
Führen Sie das Python-Unittest-Modul in vs2017 aus
Ich habe die Warteschlange in Python geschrieben
Berechnen Sie den Vormonat in Python
Untersuchen Sie die Klasse eines Objekts mit Python
Holen Sie sich den Desktop-Pfad in Python
Versuchen Sie es mit dem Python Cmd-Modul
Holen Sie sich den Hostnamen in Python
Greifen Sie mit Python auf die Twitter-API zu
Der erste Schritt von Python Matplotlib
Ich habe den Stack in Python geschrieben
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Laden Sie das Remote-Python-SDK mit IntelliJ
Versuchen Sie es mit der Wunderlist-API in Python
[Blender x Python] Lass uns das Material beherrschen !!
Lernen Sie das Designmuster "Flyweight" in Python
Versuchen Sie, die Kraken-API mit Python zu verwenden
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Proxy" in Python
Schreiben Sie den Test in die Python-Dokumentzeichenfolge
Übergeben Sie den Pfad des importierten Python-Moduls
Warteschlangen- und Python-Implementierungsmodul "deque"
Lernen Sie das Entwurfsmuster "Befehl" in Python
Vergleich japanischer Konvertierungsmodule in Python3
Nehmen Sie die logische Summe von List in Python (Zip-Funktion)
Zeigen Sie Python 3 im Browser mit MAMP an
Tweet mit der Twitter-API in Python
Lernen Sie das Entwurfsmuster "Besucher" mit Python
Überprüfen Sie, ob die URL in Python vorhanden ist
Lernen Sie das Entwurfsmuster "Mediator" mit Python
Ordnen Sie die in pythons models.py festgelegte Tabelle zu
Lernen Sie das Designmuster "Decorator" mit Python
Führen Sie den Python-Interpreter im Skript aus
Das Ergebnis der Installation von Python auf Anaconda
Was ist "Mahjong" in der Python-Bibliothek? ??
Lesen Sie die Datei Zeile für Zeile mit Python
Lesen Sie die Datei Zeile für Zeile mit Python
[Python] Importieren Sie das Modul eine Ebene höher
Überprüfen Sie den Pfad des importierten Python-Moduls
Modul zum Generieren des Wortes N-Gramm in Python
MongoDB mit Python zum ersten Mal
Lernen Sie das Entwurfsmuster "Iterator" mit Python
Grundlagen zum Ausführen von NoxPlayer in Python
Lernen Sie das Entwurfsmuster "Strategie" mit Python