2017-07-12 3 views
2

Zum Beispiel im Konstruktor muss ich einige Ressourcen greifen, die fehlschlagen könnten, in diesem Fall sollte die Klasse nicht instanziiert werden.In Python, was ist der richtige Weg, um eine Klasse zu implementieren, deren Konstruktor fehlschlagen könnte?

Sollte ich Exception im Konstruktor auslösen?

class Foo(object): 
    def __init__(self): 
     self.rsc = get_resource(): 
     assert self.rsc 

Und versuchen, es im Instanziierungscode zu fangen?

try: 
    a = Foo() 
except: 
    a = None 

Dann überprüft später Code, ob a keiner ist.

+2

besser, nur 'rsc' als Konstruktor Parameter hinzufügen, die in übergeben wird. Als Ergebnis erhalten Sie zwei Vorteile: einen leichteren Konstruktor und einen, der nicht ausfallen kann. Wenn Sie möchten, können Sie eine Funktion bereitstellen, die die Ressource implizit abruft und entweder None zurückgibt oder den Konstruktor mit der Ressource aufruft. – amalloy

+0

Was Sie vorgeschlagen haben, klingt gut. Die Frage ist, was passiert, wenn dieser Fehler auftritt. Wenn es der aufrufende Code ist, der damit umgehen muss, sollten Sie die Ausnahme im aufrufenden Code abfangen, wie Sie es vorgeschlagen haben. – BrenBarn

Antwort

3

meinen früheren Kommentar in einer Antwort Erweiterung:

Es ist besser, die Ressource als Konstruktor Parameter hinzuzufügen, wie folgt aus:

class Foo(object): 
    def __init__(self, rsc): 
     self.rsc = rsc 

Dieser Ansatz hat eine Reihe von Vorteilen:

  • Der Konstruktor kann nicht mehr
  • scheitert nicht mehr Sie haben einen teueren Konstruktor
  • Sie haben loseren Kopplung zwischen Foo und seinem Ressourcentyp

Und wenn Sie die Schnittstelle zum impliziten Erwerben einer Ressource mögen, ist es einfach, dies zu umbrechen. Eine einfache Funktion wie make_foo versucht, die Ressource automatisch zu erwerben, keine Rückkehr (oder einen Fehler erhöhen, wenn Sie bevorzugen), wenn es nicht möglich ist:

def make_foo(): 
    rsc = get_resource() 
    if rsc: 
     return Foo(rsc) 
    else: 
     return None 
-3

Nicht wirklich ein Problem, fügen Sie einfach try...except in der init Funktion und haben sie einen bestimmten Wert wie None im Falle des Scheiterns zuweisen, oder fügen Sie zusätzliche Funktionen

class Foo(object): 
    def __init__(self): 
     try: 
      self.rsc = get_resource() 
      self.success = True 
     except: 
      self.rsc = None 
      self.success = False 

a = Foo() 
if a.success: 
    print(a.rsc) 
else: 
    do_something_else() 
+0

könnte jemand sich darum kümmern, warum die downvotes? –

+0

Ich habe die Bewertung abgelehnt, weil diese Schnittstelle es sehr einfach macht, mit dem Objekt falsch zu arbeiten, indem Sie vergessen zu überprüfen, ob es erfolgreich erstellt wurde. Außerdem ist es syntaktisch ungültig, mit einem nachträglichen Zusatz ':'. – amalloy

+0

entfernt die ':' so tnx, aber ich sehe kein Problem mit Ihrem Problem zu vergessen zu überprüfen, können Sie sehr gut vergessen zu überprüfen, ob 'get_resource' selbst außerhalb einer Klasse fehlgeschlagen –

Verwandte Themen