Code: Alles auswählen
class Klob(object):
def __new__(cls,folge=None):
if folge==None: return Klob(folge=31415926535)
else: return Klob(folge=folge)
def __init__(self,folge): self.folge=folge
Code: Alles auswählen
class Klob(object):
def __new__(cls,folge=None):
if folge==None: return Klob(folge=31415926535)
else: return Klob(folge=folge)
def __init__(self,folge): self.folge=folge
Code: Alles auswählen
class Klob(object):
def __init__(self,folge=31415926535): self.folge=folge
Code: Alles auswählen
class Klob(object):
def __init__(self,folge):
assert not folge==None
self.folge=folge
def __repr__(self): return "Klob("+str(self.folge)+")"
#viele_weitere_wichtige_Methoden
_Klob=Klob
class Klob(_Klob):
#verfuegt ueber saemtliche Methoden vom alten Klob
def __new__(cls,folge=None):
if folge==None: return _Klob(folge=31415926535)
else: return _Klob(folge=folge)
Ganz meine Frage. Ich habe bisher keine Ahnung, wofür die Methode __new__ gut sein soll, und suche nach Anwendungsbeispielen, die alle verkrampft ausfallen. Aber wie wir schon von Perl wissen: "There-is-more-than-one-way-to-do-it" . Schade, dass die Methode __init__ kein "return" oder "self=..." annimmt; das wird wohl eine Altlast von Python sein.Zap hat geschrieben:Wo ist der Vorteil?
Code: Alles auswählen
class Klob(object):
def __init__(self, folge=31415926535):
self.folge = folge
Wenn du das Verhalten der Klasse grundlegend ändern willst oder gar etwas anderes Zurückgeben willst oder generell seltsame Sachen.Goswin hat geschrieben:Ich habe bisher keine Ahnung, wofür die Methode __new__ gut sein soll
Code: Alles auswählen
In [17]: class Int16(int):
....: def __new__(cls, val):
....: return int.__new__(cls, val, 16)
....:
....: def __str__(self):
....: return "%X" % self
....:
....:
In [18]: Int16("10")
Out[18]: 16
In [19]: print Int16("10")
10
Vielleicht vereinfache ich meine Beispiele zuviel.snafu hat geschrieben:Ich glaube du denkst einfach nur zu kompliziert.
Wie schon erwähnt wegen dem rekursiven Aufruf.Goswin hat geschrieben:Folgender Code ist falsch (erzeugt unendliche Rekursion), aber warum bloss?
Code: Alles auswählen
class Klob(object):
def __new__(cls,folge=None):
if folge==None: return object.__new__(cls, folge=31415926535)
else: return object.__new__(cls, folge=folge)
def __init__(self,folge): self.folge=folge
Code: Alles auswählen
class Klob(object):
def __new__(cls,folge=31415926535):
self = object.__new__(cls)
#
#Instanzierung hier, abhaengig vom Wert von folge
self.rep = "Klob("+str(folge)+")"
#alle Anweisungen vom ursprünglichen def __init__(self)
#
return self
klob = Klob(folge=123); print klob.rep
klob = Klob(); print klob.rep
Code: Alles auswählen
In [100]: class Klob(object):
.....: def __init__(self, folge=31415926535):
.....: self.folge = folge
.....: def __str__(self):
.....: return 'Klob(%s)' % self.folge
.....:
.....:
In [101]: klob = Klob()
In [102]: print klob
Klob(31415926535)
In [103]: klob = Klob(folge=123)
In [104]: print klob
Klob(123)
Natürlich, siehe EDIT. Das mache ich eigentlich auch immer so. War vielleicht verwirrt von den ganzen Konstrukten des OP's. ;PNocta hat geschrieben:Kann man dann nicht auch einfach die Folge im Falle von ``not folge``als Defaultparameter setzen, anstatt des If-Konstruktes?
Code: Alles auswählen
In [145]: Newklob = lambda: klob
In [146]: newklob = Newklob()
Kann die Fabrikfunktion nicht nach der Prüfung auf Existenz der Speicherdatei direkt entscheiden ob sie das Pickle-File lädt oder das Objekt neu erzeugt? Ich verstehe wie gesagt nicht warum man den Umweg über einen String gehen muss. Wenn du nur den Befehl zur Initialisierung an einen Namen zur späteren Verwendung binden willst, dann nutze - wie gezeigt - ein Lambda-Konstrukt als Rückgabewert der Fabrikfunktion. Natürlich übergibst du lambda dann keinen String sondern direkt den Befehl. Er wird ja dann noch nicht ausgeführt.Goswin hat geschrieben:Bei speicherdatei==None soll das Objekt neu erzeugt werden, was zeitraubend ist. Bei speicherdate<>None wird es mit Hilfe des Pickle-Moduls schnell wiederhergestellt. Um das zu realisieren, benutze ich derzeit eine Fabrikfunktion.
Nein, das Problem ist einfach, dass __init__ mit den selben Argumenten wie __new__ aufgerufen wird (siehe Beschreibung von __new__ in der Doku), deswegen gibt es bei Klob() einen Fehler, da __init__ zwei Argumente erwartet.Goswin hat geschrieben:alle Argumente von "object.__new__" außer dem ersten werden verworfen.
Code: Alles auswählen
class Test(object):
def __init__(self, val=345):
self.val = val if isinstance(val, int) else 345
def __repr__(self):
return '<Test with value of %i>' %self.val
Code: Alles auswählen
In [31]: Test()
Out[31]: <Test with value of 345>
In [32]: Test(None)
Out[32]: <Test with value of 345>
In [33]: Test("foo")
Out[33]: <Test with value of 345>