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.
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.
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.
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.
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