Python Magie

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Hallo,

Ich habe im Open Source Code von PyDrive folgende Klasse gefunden, deren Objekte als Werten von Attributen verwendet wird.
Statt age = None wird in einer Klasse Person age = APIAttribute("age") definiert. Könnt ihr mir erklären wieso diese Klasse verwendet wird?

Code: Alles auswählen

class ApiAttribute(object):
    """A data descriptor that sets and returns values."""
    def __init__(self, name):
        """Create an instance of ApiAttribute.

    :param name: name of this attribute.
    :type name: str.
    """
        self.name = name
    
    def __get__(self, obj, type=None):
        """Accesses value of this attribute."""
        return obj.attr.get(self.name)
    
    def __set__(self, obj, value):
        """Write value of this attribute."""
        obj.attr[self.name] = value
        if obj.dirty.get(self.name) is not None:
            obj.dirty[self.name] = True
    
    def __del__(self, obj):
        """Delete value of this attribute."""
        del obj.attr[self.name]
        if obj.dirty.get(self.name) is not None:
            del obj.dirty[self.name]
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

Das ist eine Descriptor und wie er funktioniert kannst Du hier nachlesen.
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

Hallo Sirius3,

Der Artikel hat mein Hintergrundwissen verbessert, aber ich würde trotzdem wenn überhaupt property verwenden.
Mir war weiterhin nicht klar, warum man sich für die Attribute merken will, ob diese gesetzt wurden. Das weiß man ja schon, wenn sie nicht None sind.
Aber dann ist mir eingefallen, dass der zugewiesene Wert ja auch None sein kann. Soweit ich es begreife werden mithilfe der Klassen Attribute beobachtet, sodass man weiß, ob sie verändert wurden, um diese dann selektiv hochzuladen. Das heißt, dass irgendwo die Attribute auch auf dirty = False gesetzt werden müssen.
Warum das bei der Klasse GoogleAuth eine Rolle spielen soll ist mir nicht klar, da sie keine Datei darstellt, die mit Google Drive synchronisiert werden muss. Da muss ich mich wohl weiter einlesen.

Boa
BlackJack

@Boa: Wenn Du `property()` dafür verwendest müsstes Du für jedes dieser Attribute drei Methoden hinzufügen in denen immer genau das gleiche steht. Das verletzt das DRY-Prinzip. Und wenn man mal etwas ändern möchte, zum Beispiel aus dem Wörterbuch `dirty` eine Menge zu machen, muss man über das ganze Programm verteilt überall die entsprechenden Property-Methoden ändern, statt das einmal in dieser Klasse zu erledigen.
Boa
User
Beiträge: 190
Registriert: Sonntag 25. Januar 2009, 12:34

@BlackJack: Wie gesagt, ich weiß nicht, warum die Klasse fast für alle Attribute eingesetzt wird. Das scheint mir auf den ersten Blick nicht sinnvoll. Ich sehe ein, dass der gewählte Ansatz deutlich flexibler ist, da die Klasse wiederverwendbar ist, jedoch ist sie deutlich schlechter lesbar. Aber es scheint ein größeres Konzept dahinter zu stehen. Für eine einzelne Klasse würde ich durchaus lieber ein paar getter und setter schreiben, aber da ich auch in Java programmiere bin ich das eher gewohnt :)
BlackJack

@Boa: Es ist ein allgemeiner Mechanismus um eine Menge von Attributen zu haben die in einem separaten Wörterbuch gespeichert werden und bei denen man feststellen kann welche Werte „dirty” sind, also verändert wurden. Das ist doch eigentlich kein so schwieriges Konzept und ich weiss auch nicht was an der Klasse so kompliziert sein soll.

Du schreibst ja selber es wird für viele Attribute verwendet, da würdest Du dann also jedes mal drei Methoden mit fast identischem Inhalt schreiben wollen!?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Es müsste übrigens __delete__ und nicht __del__ sein. __del__ hat eine andere Signatur und tut etwas völlig anderes.
Antworten