Variable in Klasse Automatisch ändern?

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
Purefranky
User
Beiträge: 8
Registriert: Montag 21. April 2008, 20:44

Tach Leute.
Sorry, ich weiß einfach nicht, unter welchem sinnvollen Begriff ich das suchen soll, da gibt´s sicher nen Fachbegriff zu.

Geht um Folgendes, ich hab ne Klasse

Code: Alles auswählen

Class Kraft():
    x=0.0;
    y=0.0;
    gesamt=0.0;
    winkel=0.0;
Jetzt würd ich gerne "gesamt" und "winkel" errechnen lassen, sobalt x bzw. y geändert werden. Mir schwirrt im Kopf rum, dass man das automatisch lösen lassen kann, indem man es in der Klasse einträgt, aber vll. verwechsel ich´s auch mit ner anderen Sprache.

Also kurzum, geht das?

Mfg PureFranky
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Wenn ich mir ansehe, was du da so machst, glaube ich wirklich, dass du eine andere Sprache meinst. Aber das was du da willst, würde man wahrscheinlich mit __setattr__ umsetzen.
Purefranky
User
Beiträge: 8
Registriert: Montag 21. April 2008, 20:44

Na das geht ja flott hier :D .
Danke, ich werd mal schaun, was sich damit machen lässt.
Bisher komm ich immer in ne dauer-Rekursion, kann ich den Aufruf von __setattr__ verhindern? Hier mal ein Beispiel:

Code: Alles auswählen

class Dings():
    wert1=0;
    def __setattr__(self, name, value):
          if name=='wert1':
             self.wert1=value;
             self.wert2=self.wert1**2;
             print(name);
             print('Jo');
             return value;
    wert2=0;

ls=Dings();
ls.wert1=5;
print(ls.wert1);
print(ls.wert2);
ls.wert1=90;
print(ls.wert1);
print(ls.wert2);
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

Code: Alles auswählen

class Kraft():
    def __init__(self, x=0., y=0.):
        self.x = x;
        self.y = y;

    @property
    def gesamt(self):
        return ...

    @property
    def winkel(self):
        return ...
Bottle: Micro Web Framework + Development Blog
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Jo, das wäre definitiv schöner, aber mit dem Dekorator kommt man beim setzen von Werten nicht sehr weit...

Des Weiteren bist du dir im klaren, was der Unterschied zwischen Klassen und Instanzvariablen ist? Ich denke nicht, dass du die Winkel aller Instanzen ändern willst, sondern nur einer Bestimmten.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Code: Alles auswählen

    def __setattr__(self, name, value):
        self.__dict__[name] = value
        if name == 'wert1':
            self.wert2 = self.wert1 * self.wert1
MfG
HWK
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Jetzt würd ich gerne "gesamt" und "winkel" errechnen lassen, sobalt x bzw. y geändert werden.
Ich unterstelle mal, dass x und y Koordinaten im Raum sind. In dem Fall frage ich mich: Sind Raumpunkte Eigenschaften einer Kraft? Wenn ich Simulationen gerechnet habe, hatte ich meist ein Objekt mit best. Eigenschaften im Raum auf das Kräfte gewirkt haben. Das aber setzt ein grundsätzlich anderes Design voraus.

Das nur nebenbei - vielleicht liege ich mit meiner Vermutung ja auch völlig daneben.

HTH
Christian
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Purefranky hat geschrieben:

Code: Alles auswählen

class Dings():
    wert1=0;
    def __setattr__(self, name, value):
          if name=='wert1':
             self.wert1=value;
             self.wert2=self.wert1**2;
             print(name);
             print('Jo');
             return value;
    wert2=0;

ls=Dings();
ls.wert1=5;
print(ls.wert1);
print(ls.wert2);
ls.wert1=90;
print(ls.wert1);
print(ls.wert2);
Bitte tu dir selbst einen Gefallen und verwende keine ; am Zeilenende. Das macht man in Java/C/C#/C++/..., aber nicht in Python. Außerdem werden auch Attribute (so heißen Member-Variablen in Python) nicht so eingeführt wie du das machst, defnull hat dir schon gezeigt wie es richtig geht, nämlich in einer __init__-Methode. Auch hier gilt: Python ist nicht Java.

Zu deinem Problem hat dir defnull schon alles gezeigt was du brauchst. Was mich aber doch interessiert: Warum schreibst du nicht einfach eine Methode?

Code: Alles auswählen

>>> class Breakfast(object):
...     def __init__(self, beans, ham, spam):
...         self.beans = beans
...         self.ham = ham
...         self.spam = spam
...     def order(self):
...         if self.beans:
...             return 'Baked beans are off!!'
...         else:
...             return 'Ham: %s, Spam: %s' % (self.ham, self.spam)
...
>>> breakfast1 = Breakfast(1,2,3)
>>> breakfast2 = Breakfast(0,1,2)
>>>
>>> print breakfast1.order()
Baked beans are off!!
>>> print breakfast2.order()
Ham: 1, Spam: 2
>>> breakfast2.ham = 4
>>> print breakfast2.order()
Ham: 4, Spam: 2
Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
Purefranky
User
Beiträge: 8
Registriert: Montag 21. April 2008, 20:44

Hehe, is ja richtig voll geworden hier :lol: .

@CM:
Jo, du hast es erraten, ich wollte mich ma an nem FEM-Löser versuchen, mein Prof hat son Ding geschrieben, will aber den Quelltext nich rausrücken, also schreib ich ihn mir selbst, wenn ich einmal verstanden hab, wie ein Programm arbeitet, versteh ich besser, was ich in der Klausur mache.
Bin aber in Python recht eingerostet und hab auch nie was großes damit gemacht. Es soll aber nur der Löser in Python geschrieben werden, Netzgenerator und Post-Prozessor sollen in PureBasic entstehen. Da schreib ich den Quelltext blind runter und dann geht dat schneller. :roll:

@Pillmuncher: Java hab ich nie programmiert :wink:
Kommt noch von Delphi, ebenfalls Studium, hab beides durchnander geschmissen und dachte daher , das müsste so sein, also hab ich´s genutzt und nicht weiter drauf geachtet, ob Python meckert. Aber danke für den Tip :wink:
Zum Thema Methode: So'n FEM-Löser (gut, meiner wird nur ein kleiner, aber einer mit großen Netzen für richtige Geometrien und 3D) braucht recht viel Rechenaufwand. Und wenn ich 4 mal length aufrufe, geht es um einiges schneller, wenn ich erst einen festen Wert errechne und diesen dann in einer Variable speicher, als wenn ich jedes mal neu errechne.
Da sollte sich Python nicht von anderen Sprachen unterscheiden, obwohl´s ne Scriptsprache ist, oder irre ich mich?

@Defnull: Danke für den Tip mit __init__. Klassen haben wir inner Vorlesung damals nicht besprochen :shock: (Traurig, aber wahr :x ), daher kenn ich mich damit nich aus.

So, also allgemein danke, ich hab es jetzt erstmal mit ner normalen Funktion, die ich aufrufen muss probiert, so geht auch nicht jedesmal rechenzeit verloren, wenn x oder y mehrfach geändert werden, bevor length aktualisiert werden muss.

Mfg und frohes coden weiterhin
PureFranky
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

SchneiderWeisse hat geschrieben:Jo, das wäre definitiv schöner, aber mit dem Dekorator kommt man beim setzen von Werten nicht sehr weit...
Doch, ich meine dass Python 2.6 auch Dekoratoren für das Schreiben von Attributen hat.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Leonidas hat geschrieben:
SchneiderWeisse hat geschrieben:Jo, das wäre definitiv schöner, aber mit dem Dekorator kommt man beim setzen von Werten nicht sehr weit...
Doch, ich meine dass Python 2.6 auch Dekoratoren für das Schreiben von Attributen hat.
Oder mit @apply...

Code: Alles auswählen

class Example(object):
    @apply
    def myattr():
        doc = """This is the doc string."""

        def fget(self):
            return self._half * 2

        def fset(self, value):
            self._half = value / 2
 
        def fdel(self):
            del self._half

        return property(**locals())
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Purefranky: Ich glaube du suchst das hier (geht ab Python 2.6):

Code: Alles auswählen

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

class Kraft(object):

    def __init__(self, point=None, x=0.0, y=0.0):
        if point:
            self._x = point.x
            self._y = point.y
        else:
            self._x = x
            self._y = y
        self._update()

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, val):
        self._x = val
        self._update()

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, val):
        self._y = val
        self._update()

    def _update(self):
        self.gesamt = ...
        self.winkel = ...


p = Point(x=3.7, y=4.5)
f = Kraft(point=p)
print f.x, f.y, f.gesamt, f.winkel

f.x = 7.1
f.y = 2.4
print f.x, f.y, f.gesamt, f.winkel

f1 = Kraft(x=6.2, y=3.3)
print f1.x, f1.y, f1.gesamt, f1.winkel
Für ... musst du halt einfügen was noch fehlt.

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

Leonidas hat geschrieben:
SchneiderWeisse hat geschrieben:Jo, das wäre definitiv schöner, aber mit dem Dekorator kommt man beim setzen von Werten nicht sehr weit...
Doch, ich meine dass Python 2.6 auch Dekoratoren für das Schreiben von Attributen hat.
Mhm, ich sehe es gerade... kannte ich bisher nicht, mag auch an meinem 2.5 liegen.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

@pillmuncher: Gerade wenn es um mehrere Attribute geht, funktioniert es mit __setattr__ m.E. einfacher und auch < Python 2.6:

Code: Alles auswählen

    def __setattr__(self, name, value):
        self.__dict__[name] = value
        if name in ('x', 'y'):
            self.gesamt = ...
            self.winkel = ...
MfG
HWK
Antworten