Seite 2 von 2

Verfasst: Freitag 17. April 2009, 18:51
von Barabbas
Hier findest du die entsprechenden Methoden.... http://www.python.org/doc/2.5.2/ref/numeric-types.html

Verfasst: Freitag 17. April 2009, 19:12
von sprudel
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

Verfasst: Freitag 17. April 2009, 19:31
von derdon
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'

Verfasst: Freitag 17. April 2009, 21:09
von str1442
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.

Verfasst: Freitag 17. April 2009, 21:15
von derdon
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])

Verfasst: Samstag 18. April 2009, 09:57
von sprudel
was bedeutet das @property ?

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

LG Chris

Verfasst: Samstag 18. April 2009, 10:25
von Barabbas
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

Verfasst: Samstag 18. April 2009, 11:34
von HWK
Die __str__-Methode muss auch einen String zurückliefern, z.B.:

Code: Alles auswählen

return str(self.amount)
MfG
HWK

Verfasst: Samstag 18. April 2009, 12:29
von 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.

Verfasst: Samstag 18. April 2009, 14:51
von Barabbas
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*.

Verfasst: Samstag 18. April 2009, 16:13
von str1442
Barrabas: Nenn es lieber Instanzmethode, eine Klassenmethode ist was anderes (help(classmethod)). Und amount ist ein Attribut des Objektes, nicht der Klasse.

Verfasst: Samstag 18. April 2009, 16:41
von Barabbas
*lol* danke für den Hinweis - ich stolpere gerne noch über bestimmte Begrifflichkeiten und bitte um Nachsicht.

Verfasst: Samstag 18. April 2009, 20:34
von Darii
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)

Verfasst: Samstag 18. April 2009, 21:00
von Trundle
@Darii: Was meinst du genau mit "nicht-trivial"?

Verfasst: Samstag 18. April 2009, 21:17
von Darii
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...;)

Verfasst: Dienstag 21. April 2009, 17:31
von sprudel
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

Verfasst: Dienstag 21. April 2009, 18:39
von fred.reichbier
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