Eigenes Objekt?
Hmm, ich glaube ich stelle mich gerade etwas dumm an:
Das erzielt irgendwie nicht den gewünschen Effekt, was mach ich da falsch?
TypeError: unsupported operand type(s) for /: 'float' and 'instance'
LG Chris
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
statt deinen komischen Typüberprüfungen solltest du isinstance nehmen:
Und noch ein Beispiel:
Code: Alles auswählen
if isinstance(num, int):
return 'yes, num is an int!'
Code: Alles auswählen
if isinstance(num, (int, float)):
return 'num is either an int or a float'
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.
CURRENCIES würd ich definitiv als Klassenvariable benutzen, passt einfach in den Klassenraum rein.
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])
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
lG
Daniel
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
lG
Daniel
Die __str__-Methode muss auch einen String zurückliefern, z.B.:MfG
HWK
Code: Alles auswählen
return str(self.amount)
HWK
@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.
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*.
Aber es ist doch schön, dass man sich beim Entwurf seiner Klassen über solche Dinge Gedanken macht *schwärm*.
Ich würde es wohl so implementieren(grob orientiert an jscience)
money.py
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)
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...
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
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
-
- User
- Beiträge: 155
- Registriert: Freitag 29. Dezember 2006, 18:27
Hm, mal zu den Properties. Interessehalber, was spricht gegen das hier?
gibt mir
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
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