2017-04-18 7 views
2

MyClass zurückgegeben wird, die unten definiert ist, akzeptiert ein einzelnes Argument arg.So geben Sie None zurück, während die Klasseninstanz

class MyClass(object): 
    def __init__(self, arg): 
     super(MyClass, self).__init__() 
     if not isinstance(arg, int): 
      return None 
     else: 
      self.arg = arg 

Wenn das eingehende Argument arg nicht eine ganze Zahl ist, würde Ich mag keine Rückkehr statt der Instanz von MyClass.

a = MyClass(arg='Text Argument') 

Aber auch während MyClass Konstruktor __init__ None zurückgibt, wenn die arg die resultierende Variable a ist immer noch eine Instanz von MyClass nicht eine ganze Zahl ist:

print a 
<__main__.MyClass object at 0x0000000001FDEFD0> 

Wie sicherzustellen, dass die Variable aNone bleibt, wenn MyClass ist ein nicht ganzzahliges Argument gegeben?

Antwort

5

Sie sollten None nicht von einem Konstruktor zurückgeben, auch wenn es möglich war. Das Ergebnis von MyClass() sollte immer eine Instanz von MyClass oder einer kompatiblen Klasse sein. alles andere wäre sehr überraschend und fehlerinduzierendes Verhalten.

Sie könnte tun dies mit einer benutzerdefinierten __new__ Methode, die die tatsächliche Instanz erstellt. Aber nochmal, ich würde es nicht empfehlen.

Sie sollte eine Ausnahme sein Anheben, wenn das Objekt nicht mit der angegebenen Daten aufgebaut sein:

class MyClass(object): 
    def __init__(self, arg): 
     super(MyClass, self).__init__() 
     if not isinstance(arg, int): 
      raise TypeError('arg must be an int') 

     ... 
+0

Das explizite Zurückgeben von 'None' ist OK (oder einfach' return' von selbst), da dies standardmäßig geschieht. Sie könnten es früh tun, um die '__init __()' -Methode zu verlassen, nehme ich an, aber das hat keinen Einfluss darauf, ob die Instanz erzeugt wird oder nicht - nur möglicherweise der Anfangszustand, den sie hat. – martineau

+1

Wahr, das war etwas mehrdeutig formuliert. Ich meinte * wenn der Rückgabewert einen Unterschied machen würde, solltest du es immer noch nicht machen. * – deceze

+0

Egal was du meintest, mein Punkt war, dass das was du sagst nicht genau ist: Es ist nicht nur möglich, es ist denkbar ein Grund, dies zu tun, wohl wissend, dass es nicht verhindert, dass die Instanz erstellt wird.Was scheint nicht zu sein, was das OP erreichen möchte. – martineau

2

Sie in der Regel tun dies nicht, aber Sie können, wenn Sie wollen, von zwingende Ihre __new__, wo die neue Instanz erstellt:

class MyClass(object): 
    def __new__(cls, **kwargs): 
     if not isinstance(kwargs['arg'], int): 
      return None 
     return super(MyClass, cls).__new__(cls, **kwargs) 

    def __init__(self, arg): 
     super(MyClass, self).__init__() 
     self.arg = arg 

die __init__ Methode nicht erstellen die Instanz, es initialisiert es nur, None von ihm zurückgegeben wird, was erwartet wird. Wenn __new__ ein Objekt zurückgibt, das keine Instanz ist (wie None in diesem Fall), wird __init__ nicht aufgerufen.

Einer der Gründe, warum Sie nicht die oben verwenden sollte, ist die folgende:

print isinstance(MyClass(arg='666'), MyClass) #-> False 
# waaah! 

Viele Dinge beginnen in Ihrem Code zu brechen, und der oben ist nur ein Beispiel dafür.

Verwandte Themen