2017-04-18 11 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のインスタンスのNoneを返したい整数でない場合。

a = MyClass(arg='Text Argument') 

しかしargは、結果の変数a整数でない場合Noneを返す__init__MyClassコンストラクタはまだMyClassのインスタンスである間も:

print a 
<__main__.MyClass object at 0x0000000001FDEFD0> 

変数aNoneかのまま確認するために、どのようにMyClassには非整数の引数が与えられていますか?

答えて

5

可能であれば、コンストラクタからNoneを返さないでください。 MyClass()の結果は常に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'を返すことは、デフォルトで起こることになるので、OK(または単に' 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 

メソッドはインスタンスを作成しません。インスタンスを初期化するだけで、Noneが返されます。

この場合、__new__はインスタンスではないオブジェクト(この場合はNoneなど)を返します。__init__は呼び出されません。

あなたは上記を使用してはならない理由の一つは以下の通りです:

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

多くのことは、あなたのコード内で破る開始し、上記はほんの一例です。

関連する問題