Eigenes Objekt?

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.
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Hier findest du die entsprechenden Methoden.... http://www.python.org/doc/2.5.2/ref/numeric-types.html
sprudel
User
Beiträge: 250
Registriert: Donnerstag 8. März 2007, 17:12

Hmm, ich glaube ich stelle mich gerade etwas dumm an:

Code: Alles auswählen

    def __add__(self,amount):
        if type(amount) != "<type 'float'>" and type(amount) != "<type 'int'>": amount = LightMoney(amount)
        return float(self.GetValue()+amount)
    def __sub__(self,amount):
        if type(amount) != "<type 'float'>" and type(amount) != "<type 'int'>": amount = LightMoney(amount)
        return float(self.GetValue()-amount)
    def __mul__(self,amount):
        if type(amount) != "<type 'float'>" and type(amount) != "<type 'int'>": amount = LightMoney(amount)
        return float(self.GetValue()*amount)
    def __div__(self,amount):
        if type(amount) != "<type 'float'>" and type(amount) != "<type 'int'>": amount = LightMoney(amount)
        return float(self.GetValue()/amount)

Das erzielt irgendwie nicht den gewünschen Effekt, was mach ich da falsch?

TypeError: unsupported operand type(s) for /: 'float' and 'instance'

LG Chris
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

statt deinen komischen Typüberprüfungen solltest du isinstance nehmen:

Code: Alles auswählen

if isinstance(num, int):
    return 'yes, num is an int!'
Und noch ein Beispiel:

Code: Alles auswählen

if isinstance(num, (int, float)):
    return 'num is either an int or a float'
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

type(obj) ist kein String, sondern die Klasse des jeweiligen Objektes (außerdem gibt es auch das .__class__ Attribut bei beliebigen Objekten, aber was man davon nutzt ist sicherlich Stilfrage).

CURRENCIES würd ich definitiv als Klassenvariable benutzen, passt einfach in den Klassenraum rein.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Getter sind übrigens keine gute Idee (genauso wie Setter).

Code: Alles auswählen

class Money(object):
    def __init__(self, amount, currency="EUR"):
        self.amount = float(amount)
        self.currency = currency

    def __str__(self):
        return self.amount

    def __add__(self, amount):
        return float(self.amount_in_standard_currency + amount.amount_in_standard_currency)

    def __sub__(self, amount):
        return float(self.amount_in_standard_currency - amount.amount_in_standard_currency)

    @property
    def amount_in_standard_currency(self):
        return float(self.amount * CURRENCIES[self.currency])
sprudel
User
Beiträge: 250
Registriert: Donnerstag 8. März 2007, 17:12

was bedeutet das @property ?

Und ich möchte bei isinstance nicht "instance" rauskriegen, sondern was anderes. Wie mache ich das?

LG Chris
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

Mit Property kannst du eine Klasseneigenschaft (wie amount.amount) an eine Klassenmethode umleiten, so dass du z.B. noch Operationen ausführen kannst, wenn jemand eine Klasseneigenschaft liest / setzt.

Allerdings sehe ich das etwas als derdon: get_amount_in_standard_currency() ist eine normale Klassenmethode - dahinter verbirgt sich ja nicht direkt eine Eigenschaft. Würde ich das ganze umbenennen in "calculate_amount_in_standard_currency()" wäre wahrscheinlich nichtmal moniert worden, dass hier Getter verwendet würden.
Dieses ganze Getter/Setter-Ding bezieht sich m.E. eher darauf, dass man seine Programmierung nicht mehr von vornherein auf G/S auslegen muss, da man mit properties später immernoch entsprechende Methoden implementieren kann. Das heißt aber nicht, dass man alle Methoden, die etwas zurück geben, in Eigenschaften verwandeln muss :wink:

lG

Daniel
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Die __str__-Methode muss auch einen String zurückliefern, z.B.:

Code: Alles auswählen

return str(self.amount)
MfG
HWK
BlackJack

@Barabbas: Man kann aber auch durchaus den Betrag in der Referenzwährung als Eigenschaft von einem "Geldbetrag"-Objekt sehen. Der Name ist natürlich schlecht gewählt, weil `get_*()` eine Tätigkeit beschreibt und deshalb eher zu einer Methode gehört.
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

ja, habe ich auch erst überlegt - aber prinzipiell hat man ja eine Währung und kann diese durch Umrechnung in eine andere Währung übertragen. Der Betrag einer bestimmten Summe in einer anderen beliebigen Währung ist dann natürlich keine Eigenschaft der ursprünglichen Summe. Daher meine Überlegung. Im Falle der (vorher festgelegten) Referenzwährung könnte man wahrscheinlich aber wirklich darüber streiten.

Aber es ist doch schön, dass man sich beim Entwurf seiner Klassen über solche Dinge Gedanken macht *schwärm*.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Barrabas: Nenn es lieber Instanzmethode, eine Klassenmethode ist was anderes (help(classmethod)). Und amount ist ein Attribut des Objektes, nicht der Klasse.
Barabbas
User
Beiträge: 349
Registriert: Dienstag 4. März 2008, 14:47

*lol* danke für den Hinweis - ich stolpere gerne noch über bestimmte Begrifflichkeiten und bitte um Nachsicht.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Ich würde es wohl so implementieren(grob orientiert an jscience)
money.py

Code: Alles auswählen

from money import Money, Currency    

EUR = Currency("EUR")
USD = Currency("USD")

# Hier leider Setter notwendig, da properties auf Klassen in python nicht-trivial sind
Currency.set_reference_currency(EUR)
USD.exchange_rate = 0.765872712

print Money(5, USD).convert_to(EUR)
print Money(10, EUR) + Money(5, USD)
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

@Darii: Was meinst du genau mit "nicht-trivial"?
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Siehe Antwort 1: http://stackoverflow.com/questions/1285 ... assmethods , das war mir jedenfalls zuviel Stress für zwei Funktionen. Ich habs auch nur geschrieben, damit nicht irgendwer wegen dem Setter rummeckert...;)
sprudel
User
Beiträge: 250
Registriert: Donnerstag 8. März 2007, 17:12

So, jetzt hab ich das ganze ins Kassensystem eingebaut, funktioniert auch soweit.

JEtzt habe ich nur das Problem: Bei der Eingabe von Geldsummen in verschiedenen Methoden habe ich das Problem dass ich gleich alles wieder durch die Klasse Money jage, so wird die Einheit quasi wieder vergessen.
Habt ihr da eine Idee wie ich überprüfen kann, ob der Eingabewert der Klasse entspricht?

LG Chris
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Hm, mal zu den Properties. Interessehalber, was spricht gegen das hier?

Code: Alles auswählen

class Meta(type):
    def _set_foo(cls, foo):
        print '_set_foo fuer', cls
        cls._foo = foo

    def _get_foo(cls):
        print '_get_foo'
        return cls._foo

    foo = property(_get_foo, _set_foo)

class A(object):
    __metaclass__ = Meta

class B(A):
    pass

A.foo = 123
print A.foo
print B.foo
B.foo = 456
print A.foo
print B.foo
gibt mir

Code: Alles auswählen

_set_foo fuer <class '__main__.A'>
_get_foo
123
_get_foo
123
_set_foo fuer <class '__main__.B'>
_get_foo
123
_get_foo
456
Antworten