2013-06-27 4 views
7

Zunächst einmal weiß ich, dass die __init__()-Funktion einer Klasse in Python keinen Wert zurückgeben kann, so leider diese Option nicht verfügbar ist.Python __init__ Rückgabe fehlgeschlagen zu erstellen

Aufgrund der Struktur meines Codes ist es sinnvoll, Datenbestätigungen (und Aufforderungen an den Benutzer zur Angabe von Informationen) innerhalb der __init__-Funktion der Klasse zu haben. Dies bedeutet jedoch, dass die Erstellung des Objekts fehlschlagen kann, und ich möchte in der Lage sein, dies in eleganter Weise wiederherzustellen.

Ich fragte mich, was der beste Weg, um damit fortzufahren ist. Ich habe darüber nachgedacht, einen globalen booleschen Wert als "gültige Konstruktion" -Flag zu setzen, aber ich würde es lieber nicht tun.

Alle anderen Ideen (abgesehen von der Umstrukturierung so Assertions kann außerhalb der Initialisierung passieren und Werte werden als Argumente übergeben)? Ich bin im Grunde auf der Suche nach einer Möglichkeit, 0 bei Erfolg zurückgeben und -1 bei einem Fehler während der Initialisierung zurückgeben. (Wie die meisten C-Systemaufrufe)

+8

Eine Ausnahme auslösen. –

+1

Rückgabe 0 bei Erfolg und -1 bei Ausfall ist sehr un-Pythonic. Fehlerrückmeldungen sind schlecht, weil sie einfach zu ignorieren und ausführlich zu behandeln sind. Obendrein führt die Verwendung von 0 und -1 als boolescher Wert nur zu Verwirrung ohne Nutzen. Benutze Python nicht, um C-Code zu schreiben. – abarnert

+0

Wie @jsbueno in seiner Antwort darauf hinweist, werden Klasseninstanzen _initialized_ in '__init __()' nicht erstellt, weshalb sie keinen Wert zurückgibt. Anstatt eine globale Variable zu verwenden, um Fehler zu erkennen oder eine Ausnahme auszulösen, können Sie der Klasse einen Datenmember hinzufügen, um dessen Status anzuzeigen, und dann den Wert direkt überprüfen oder eine Methode aufrufen, die ihren Wert nach '__init __() 'zurückgibt wurde aufgerufen, um festzustellen, ob etwas (und möglicherweise was) wenn falsch. – martineau

Antwort

11

Sie könnten eine Ausnahme auslösen, wenn entweder assertio scheitern, oder - wenn Sie wirklich nicht wollen oder können mit Ausnahmen nicht funktionieren, können Sie die __new__ Methode in Klassen schreiben - in Python, ist __init__ technisch ein "Initialisierer" -Methode - und es sollte die Attribute ausfüllen und einige der Ressourcen und andere erwerben, die Ihr Objekt während seines Lebenszyklus benötigt - Allerdings definiert Python einen echten Konstruktor, die __new__-Methode, die vor __init__ aufgerufen wird - und Im Gegensatz dazu gibt __new__ tatsächlich einen Wert zurück: die neu erstellte (nicht initialisierte) Instanz selbst.

So können Sie Ihre Schecks innerhalb __new__ und und einfach Zurück None ist etwas schlägt fehl - andernfalls, das Ergebnis des Aufrufs an die Superklasse __new__ Methode zurück (man kann nicht die tatsächliche Speicherzuweisung für das Objekt in reinem Python , so letztlich müssen Sie in nativen Code in einer übergeordneten Klasse geschrieben, um einen Konstruktor aufrufen - in der Regel diese object.__new__ in der Basis der Klassenhierarchie ist

NB. in Python 2 müssen Sie object als Basisklasse für Ihre Hierarchie - sonst wird nicht nur __new__ aufgerufen, da viele Funktionen, die später zu Python-Objekten hinzugefügt werden, einfach nicht funktionieren. class MyClass(object):, nie class MyClass: - außer Sie sind auf Python3.

+0

Sie sagen, dass "__new__" vor "__init__" aufgerufen wird. Ich habe das gerade versucht, aber '__new__' wird NICHT aufgerufen, wenn ich eine Instanz einer Klasse (Py2.7) erstelle. –

+0

Ich habe es gefunden. Sie müssen das Objekt in Ihrer Klasse erweitern. Ohne das wird neu nicht aufgerufen! –

+0

Nein. Wenn ich die Objekt-Basisklasse weglasse, wird '__new__' nicht automatisch aufgerufen. Stelle dir das vor! –

0

Haben Sie erwogen, eine Ausnahme auszulösen? Das ist der übliche Weg, um einen Fehler zu signalisieren.