2017-04-18 76 views
2

MyClass下面定義的接受單個參數arg如何在聲明類實例時返回None

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

如果傳入的參數arg不是整數,我想返回,而不是MyClass實例無。

a = MyClass(arg='Text Argument') 

但即使MyClass構造時arg不是整數所產生的變量a__init__返回無尚的MyClass一個實例:

print a 
<__main__.MyClass object at 0x0000000001FDEFD0> 

如何確保變量a仍然None如果MyClass被賦予非整數參數?

回答

5

即使可能,您也不應從構造函數返回NoneMyClass()的結果應始終爲MyClass或兼容類的實例;其他任何東西都會非常令人驚訝和錯誤誘導行爲™。

可能做一個自定義__new__方法,它會創建實際的實例。但是,我不會推薦它。

應該被拋出一個異常,如果該對象不能與給定的數據來構建:

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

     ... 
+0

顯式返回'None'確定(或者僅僅是'return'),因爲默認情況下會發生這種情況。我想盡早退出'__init __()'方法,但是這樣做不會影響實例是否被創建 - 可能只是初始狀態。 – martineau

+1

的確如此,這措辭有些含糊。我的意思是*如果返回值有任何區別,你仍然不應該這樣做* – deceze

+0

無論你的意思是什麼,我的觀點是你所說的不準確:不僅是可能的,還有可能這是完全知道它不會阻止創建實例的原因。這似乎並不是OP希望完成的。 – martineau

2

您一般不應該這樣做,但你可以,如果你想通過覆蓋__new__,其中新實例創建:

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 

__init__方法不是創建實例,它只初始化它,從它返回None是預期的。

__new__返回不是實例的對象(在本例中爲None)的情況下,將不會調用__init__

一個爲什麼你不應該使用上述原因如下:

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

很多事情將開始在你的代碼破裂,上面只是一個例子。