Hintergrund
Ich versuche, Python's Deskriptoren zu verstehen, indem ich Lutz's Learning Python Abschnitt zum Thema lese, in dem er sagt: "Wie Eigenschaften sind Deskriptoren so konzipiert, dass sie spezifische Attribute behandeln... Im Gegensatz zu Eigenschaften haben Deskriptoren ihren eigenen Zustand..."
Im Laufe des Kapitels zeigt er Beispiele, bei denen das verwaltete Attribut tatsächlich im enthaltenden/umhüllenden Objekt gespeichert ist, wie zum Beispiel:
def __set__(self, Instance, Wert):
Instance._name = Wert.lower()
Ich verstehe diese Beispiele und sie scheinen in Schreibweisen zum Thema häufig vorzukommen. Dennoch ist ihr Nutzen gegenüber Eigenschaften für mich nicht offensichtlich und sie scheinen nicht den internen Zustand zu haben, wie im obigen Zitat versprochen.
Am Ende des Kapitels zeigt er ein Beispiel, das näher an dem ist, was ich nach dem Lesen von "eigenen Zustand haben" erwartet habe, wie zum Beispiel:
def __set__(self, Instance, Wert):
self.name = Wert.lower()
Das Beispiel läuft, macht aber nicht, was ich erwarten würde. Da das Beispiel ein wenig lang ist, habe ich es auf Pastebin gestellt und eine letzte Zeile hinzugefügt, die das unerwartete Verhalten zeigt (Bob's Name ist jetzt Sue). Hier ist ein kürzeres Demosnippet:
Klasse Wrapper(objekt):
Klasse BeispielDeskriptor(objekt):
def __get__(self, Instanz, Besitzer):
print "holen %s" % self.state
return self.state
def __set__(self, Instanz, Wert):
print "setzen %s" % Wert
self.state = Wert
ex = BeispielDeskriptor()
w1 = Wrapper()
w1.ex = 1
print w1.ex
w2 = Wrapper()
print w2.ex
w2.ex = 2
print w1.ex
print w1.ex is w2.ex
Der Output davon ist:
setzen 1
holen 1
1
holen 1
1
setzen 2
holen 2
2
holen 2
holen 2
True
Nach genauerem Betrachten des Codes ist keiner dieser Ausführungen eine Überraschung. Die Validierungslogik im Deskriptor macht aus diesem Attribut auf der Wrapper-Klasse de facto ein Singleton; es ist jedoch schwer vorstellbar, dass dieser gemeinsame Zustand Lutz's Absicht war oder die Absicht in diesem weithin verlinkten Tutorial zum Thema war.
Frage
Ist es möglich, einen Deskriptor zu erstellen, der einen internen Zustand hat, der einzigartig für das umhüllende Objekt ist, ohne diesen Zustand auf den umhüllenden Objektinstanzen zu speichern (wie im ersten Snippet)? Ist es möglich, die CardHolder
-Klasse aus dem verlinkten Beispiel so zu ändern, dass Bob nicht am Ende als Sue endet?