Rect Klasse und property Funktion

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
Benutzeravatar
Don Polettone
User
Beiträge: 115
Registriert: Dienstag 23. November 2010, 20:26
Wohnort: Schweiz

Hey da mal wieder,

ich habe Mühe mit der property() Funktion in Python. Für viele die z.Bsp. von C++ her zu Python gelangen ist das glaub ich viel einfacher zu verstehen..?

Als ich in pygame auf die rect Klasse stiess war ich verwundert, dass ein rect Objekt stets weiss, wo z.Bsp. gerade die untere Mitte des rects ist (rect.midbottom) etc etc. Wenn man eine dieser Variablen ändert, passen sich alle anderen an. Jemand hatte mir damals gepostet, dies müsse durch die property Funktion (berechnete Attribute) geschehen. Ich hab mir das angeschaut und bislang hab ich meist verstanden wie's funzt wenn ich was lese, aber ich weiss noch immer nicht, wie ich nun eine rect Klasse programmieren würde wenn ich wollte. Kann mir das jemand näherbringen, dass ich's verstehe?

Wäre nett!

Cheers, danke,


Henry
Ich code, also bin ich.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Properties sind nichts anderes als syntaktischer Zucker mit dem man einen Methodenaufruf wie einen normalen Attributszugriff aussehen lassen kann.
Natuerlich kann man damit auch normale Attribute transparent durch Methoden ersetzen, die zB eine Validierung durchfuehren, aber das ist keine Magie.

Die Dokumentation hat ein ausfuehrliches Beispiel, lass uns mal darauf aufbauen: Was verstehst du dabei nicht?
Benutzeravatar
pillmuncher
User
Beiträge: 1532
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Hier ein einfacheres Beispiel. Angenommen, du möchtest Intervalle auf der Zahlengeraden verwalten. Jedes Intervall besteht aus zwei Zahlen, links und rechts, so dass stets links <= rechts ist, und falls jemand etwa ein Objekt interv = Intervall(20.0, 10.0) erzeugt, so soll interv.links == 10.0 und interv.rechts == 20.0 und interv.mid == 15.0 sein. Dann könnte man das zB. so implementieren:

Code: Alles auswählen

def sort2(a, b):
    return (b, a) if a > b else (a, b)


class Interval(object):

    def __init__(self, left, right):
        self._set(left, right)

    def _set(self, left, right):
        left, right = sort2(left, right)
        self._left = left
        self._right = right

    @property
    def left(self):
        return self._left

    @left.setter
    def left(self, value):
        self._set(value, self._right)

    @property
    def right(self):
        return self._right

    @right.setter
    def right(self, value):
        self._set(self._left, value)

    @property
    def mid(self):
        return (self.left + self.right) / 2.0


if __name__ == '__main__':
    interv = Interval(3.0, 7.0)
    assert interv.mid == 5.0
    interv.right = 1.0
    assert interv.left == 1.0
    assert interv.right == 3.0
    assert interv.mid == 2.0
Der property-Decorator ist bloß eine Funktion höherer Ordnung - d.h. eine Funktion, die andere Funktionen verarbeitet - und erzeugt einen sog. Descriptor. Um Properties zu verwenden braucht man nicht zwingend genau wissen, wie das funktioniert. Wichtig ist lediglich, dass dadurch ermöglicht wird, auf scheinbare Daten-Attribute eines Objekts zuzugreifen, die in Wirklichkeit Methoden sind. Es ist gewissermaßen eine der zwei Möglichkeiten in Python, den Punkt-Operator zu überladen. Die andere ist __getattribute__().
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Don Polettone
User
Beiträge: 115
Registriert: Dienstag 23. November 2010, 20:26
Wohnort: Schweiz

Hey pillmuncher, hey cofi,

Danke für das Beispiel! Ich experimentier damit mal rum, ich verstehs jetzt besser was das mit dem @ überhaupt soll auf jeden Fall. Auch das offizielle Tut hab ich nochmals in Ruhe angeschaut und passt jetzt auch schon besser.

Hat geholfen, danke!
Ich code, also bin ich.
Antworten