Seite 1 von 2
Re: __new__ vs. __init__
Verfasst: Freitag 6. Mai 2011, 17:58
von cofi
proofy hat geschrieben:Und habe jetzt wohl dadurch einen weiteren Sinn für __new__ gefunden.
Wenn man sicher gehen will, dass ein Attribut wirklich existieren soll, sollte man es wohl in der __new__ erzeugen und
Erm. Und warum sollte es deiner Meinung der Initialisierung in `__init__` ueberlegen sein?
Re: __new__ vs. __init__
Verfasst: Freitag 6. Mai 2011, 18:51
von BlackJack
@proofy: Ich schliesse mich der Frage von cofi an.
Ausserhalb vom Ableiten von "immutable" Typen und Metaprogrammierung fällt mir nur noch das Singleton-Entwurfsmuster als Anwendung ein. Von Metaklassen lasse ich in der Regel die Finger, weil man IMHO mit solcher "Magie" vorsichtig und sparsam umgehen sollte. Von nicht veränderbaren Typen leite ich anscheinend nicht ab, und Singletons setze ich um in dem ich einfach von solchen Klassen nur ein Exemplar erstelle und gut ist. Ich glaube ich habe noch nie in "normalem" Quelltext eine `__new__()`-Methode implementiert. Wenn Du das gewohnheitsmässig machst, oder demnächst machen willst, ist das IMHO ziemlich ungewöhnlich. Denn auch in anderer Leute Quelltext habe ich bisher nur sehr vereinzelt `__new__()`-Methoden gesehen.
Re: __new__ vs. __init__
Verfasst: Freitag 6. Mai 2011, 19:10
von Xynon1
Ich habe __new__ bisher auch nur einmal benutzt
http://www.python-forum.de/viewtopic.php?f=1&t=26077, da ich es dort quasi als Klassen-Fabrik nutze, was man sich auch anders hätte lösen können.
Ansonsten schließe ich mich den Vorednern auch an, da ist nichts *überlegenes* an "__new__". Es hat schlicht einen anderen Aufgabenbereich.
Re: __new__ vs. __init__
Verfasst: Montag 9. Mai 2011, 12:00
von proofy
Klassenfabrik ist z.B. eine gute Gelegenheit. Ich meine ja nicht, dass man es dauernd machen soll.
Bei mir war es z.B. aus json direkt ein Objekt aus einer übergebenen Klasse zu erzeugen.
Auch mit der Kommunikation mit "Fremdsystemen" wie .net scheint es sinnvoll zu sein, weil dort die "Fabriken" gerne __new__ aufrufen als __init__ .
Re: __new__ vs. __init__
Verfasst: Montag 9. Mai 2011, 12:05
von lunar
Für solche Zwecke würde ich eher Klassenmethoden einsetzen, e.g. "Foo.from_json(json)". Explizit, weniger magisch und daher meines Erachtens besser lesbar und leichter verständlich.
Re: __new__ vs. __init__
Verfasst: Montag 9. Mai 2011, 15:22
von Leonidas
proofy hat geschrieben:Klassenfabrik ist z.B. eine gute Gelegenheit.
Da finde ich es oftmals sinnvoller eine Funktion eine Klasse zurückgeben zu lassen, statt Metaprogramming zu machen.
Re: __new__ vs. __init__
Verfasst: Dienstag 10. Mai 2011, 16:37
von proofy
Also irgendwie driftet es doch jetzt in eine Art Glaubenskrieg ab oder ich verstehe es mal wieder nicht?
__new__ ist doch __init__ so überlegen wie Äpfel Birnen, also gar nicht und 2 völlig verschiedene Dinge.
__new__ ist doch eine Klassenmethode oder?
Mein Beispiel würde ohne __new__ nicht funktionieren.
Muss in __init__ auf jeden Fall immer alles initialisiert werden?
Wenn nicht, finde ich ein __new__ recht einfach und überhaupt nicht magisch (im Gegensatz zu lamda

So wird ein __repr__ immer funktionieren.
Re: __new__ vs. __init__
Verfasst: Dienstag 10. Mai 2011, 16:48
von Xynon1
Nochmal, du erstellst da ein neues Klassenobjekt/typ von dem du dann instanzierst. Das ist dann nicht mehr die Klasse die du angelegt hast, sondern eine Kopie davon und das jedesmal. Also in meinen Augen ist das was völlig anderes.
Python Dokumentation hat geschrieben:Class Types
Class types, or “new-style classes,” are callable. These objects normally act as factories for new instances of themselves, but variations are possible for class types that override __new__(). The arguments of the call are passed to __new__() and, in the typical case, to __init__() to initialize the new instance.
Re: __new__ vs. __init__
Verfasst: Dienstag 10. Mai 2011, 17:34
von BlackJack
@proofy: Das mit dem "überlegen sein" kommt von Deiner Behauptung `__new__()` würde irgendwie mehr garantieren bezüglich der Existenz von Attributen. Wobei ich nicht verstehe was Du damit meinst? In der `__init__()` kann man ein Objekt auch nur halb initialisieren wenn man lustig ist. Das geht mit `__new__()` aber genau so.
`__new__` ist per se nicht "magisch" aber es wird (nur) für Magie benötigt. Und wenn man keine Magie damit implementiert, kann man auch `__init__()` verwenden. Dann ist `__new__()` einfach nur das falsche, da unnötig komplexere, Werkzeug.
Welches Beispiel meinst Du denn jetzt was ohne `__new__()` nicht ginge?
Re: __new__ vs. __init__
Verfasst: Donnerstag 26. Mai 2011, 14:06
von proofy
Natürlich kann man auch alles in der __init__() machen, umgekehrt kenne ich bisher keinen Grund immer auf __new__() zu verzichten.
Das Beispiel kam aus einem Beitrag von mir vorher.
Properties lesen, die nicht gesetzt wurden. Man könnte hier auch die Abfrage in __init__ besser gestalten, damit ein default-Wert gesetzt wird.
proofy hat geschrieben:
Code: Alles auswählen
class Project(object):
def __init__(self, inName = "", inProjectNumber=0):
if inName:
self.__name = str(inName)
if inProjectNumber:
self.__projectNumber = inProjectNumber
def __new__(cls, *args, **kwds):
instance = super(Project, cls).__new__(cls)
instance.__name = None
instance.__projectNumber = -1
return instance
def __repr__(self):
return "Project: \n{\n Name: %s\n ProjectNumber: %d\n }" % (str(self.Name), self.ProjectNumber)
@property
def Name(self):
return self.__name
@property
def ProjectNumber(self):
return self.__projectNumber
Re: __new__ vs. __init__
Verfasst: Donnerstag 26. Mai 2011, 14:13
von lunar
@proofy: "__new__()" ist semantisch einfach die falsche Methode. Sie implementiert die Erzeugung eines Exemplars aus der Klasse, das Setzen von Attributen auf diesem Exemplar ist aber Teil der Initialisierung des Exemplars, gehört also in "__init__()".
Re: __new__ vs. __init__
Verfasst: Donnerstag 26. Mai 2011, 17:45
von snafu
@proofy: Das, was du da machst, ist extrem unüblich. Klar, funktioniert es auf diese Weise und letztlich kann dir ja niemand vorschreiben, wie du deine Programme schreibst. Ich bin mir aber ziemlich sicher, dass du kaum Projekte finden wirst, die so vorgehen wie du. Wenn ich so etwas in Code sehen würde, fände ich es eher abschreckend. Auf jeden Fall ist es ein Stolperstein für den Leser. Ich sehe auch nicht, welchen Vorteil dies gegenüber dem üblichen Weg mittels `__init__()` haben soll.
Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 09:35
von proofy
@lunar Gehören die Attribute beim Erzeugen eines Objektes nicht dazu?
Und wenn ja, welchen Wert sollen diese dann besitzen? Sinnvoll wäre z.B. None . Immerhin würde dann aber das Attribut existieren.
Initialisiert wird es dann mit __init__ . Finde ich eine Runde Sache. Den Schritt mehr finde ich schon ganz nützlich, muss ich aber auch nicht immer machen. Wenn ich z.B. zum Zeitpunkt der Initialisierung alle Attribute kenne und auch einen Initialwert passend dazu, mache ich natürlich auch nur ein __init__, also so zu 95%

Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 09:55
von BlackJack
@proofy: Nein die Attribute gehören zur Erzeugung des Objekts nicht dazu. Das wird in der `__init__()` gemacht. Warum die Attribute unbedingt vor der `__init__()` existieren sollten, ist mir ehrlich gesagt nicht ganz klar. Was genau bringt das, ausser dass Du mehr schreiben musst, und jeder der schon etwas länger Python programmiert, sich fragt warum das so umständlich gemacht wird!? `__new__()` ist dazu da um schon bei der Erzeugung des Objekts eingreifen zu können, was bei der `__init__()` nicht geht. Wenn man das in `__new__()` aber gar nicht nutzt, sollte man `__new__()` nicht implementieren. Attribute in `__new__()` an `None` zu binden um sie gleich danach in der `__init__()` an einen anderen Wert zu binden, finde ich eher eckig als rund. Irgendwie sinnfrei.
Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 10:03
von proofy
Bin ja der gleichen Meinung, aber gut zu wissen, dass man es könnte.
Überladen von Methoden funktioniert ja nicht bei Python. Vielleicht ist das so eine Art "Hilfskrücke".
Mit __new__() ohne Übergabeparameter zum Erzeugen des Objektes und Standardwerten in den Attributen und mit __init(json)__ das Objekt erzeugen und gleich Werte zuweisen. Mal so ein Vorschlag

und ja, es stimmt, es ist Javastyle

Sind Schlangen eigentlich Kaffeetrinker?
Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 10:31
von snafu
@proofy: Was soll dein Konstrukt denn jetzt bitte mit dem Überladen von Methoden zu tun haben bzw inwiefern wird da etwas ausgeglichen, was einem wegen diesem nicht in Python vorhandenen Feature fehlen würde? Wenn ich "überladen" will, dann nutze ich Defaultwerte für Schlüsselwortargumente und/oder Typprüfungen innerhalb der Methode. Oder meintest du, dass du irgendwie `__new__()` nutzen willst, um `__init__()` zu überladen (was ich ziemlich wirsch fände)? Ich sehe halt nicht den Zusammenhang zwischen dem Thema dieses Threads und der von dir geäußerten Idee, diese Art von "Workaround" haben zu wollen.
Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 10:39
von BlackJack
@proofy: Hilfskrücke für was denn bitte? Wenn Du alternative ”Konstruktoren” willst, dafür gibt es Klassenmethoden. Deinen Vorschlag verstehe ich nicht? Wozu braucht man da eine `__new__()`-Methode? Die `__init__()` die anscheinend mit JSON-Daten gefüttert werden soll, wird ja nach der `__new__()` mit *deren* Argumenten auch noch einmal aufgerufen. Man würde da also nur das JSON-Argument sinnlos durch eine `__new__()`-Methode schleifen, die man überhaupt nicht benötigt. Das kann man auch alles in der `__init__()` machen.
Falls Du so etwas hier meintest:
Code: Alles auswählen
class Point(object):
def __init__(self, x=0, y=0):
self.x = x
self.y = y
@classmethod
def from_dict(cls, dictionary):
return cls(dictionary['x'], dictionary['y'])
Da braucht man kein `__new__()`.
Re: __new__ vs. __init__
Verfasst: Freitag 27. Mai 2011, 12:47
von proofy
Es kommt aus der C# und Java Welt, wo in Factories Objekte z.B. aus JSON erzeugt werden. Diese werden zunächst ohne Übergabe zum Konstruktor erzeugt und dann über Properties mit "aufgefüllt" . In meinem Fall habe ich mit IronPython gearbeitet und versucht eine JSON Objekt Fabrik aus .Net unter im Silverlight-Container zu verwenden. Da wusste ich noch nichts über __new__() und diese Fabriken aus einer anderen (Programmier)welt verwenden __new__() . Und hier im Forum konnte man mir Antworten geben, um das zu verstehen. Vielen Dank noch mal.
