Pythonのクラスコンストラクター。__new__と__init__
PythonのClass(クラス)にはコンストラクターと呼ばれる特別なメソッドがあります。
コンストラクターはクラスが生成されるタイミングで自動で呼び出されるメソッドでクラス自身の設定を変更したり、インスタンス変数の初期化などを行います。
Pythonのコンストラクター
Pythonのコンストラクターには__new__()と__init__()の2つのコンストラクターが存在します。
__new__()と__init__()は呼び出されるタイミングが異なり、そこから初期化する役割が変わってきます。
コンストラクター__new__()
コンストラクターの__new__()はインスタンスオブジェクトが生成される前に呼ばれます。
クラス自体の初期化を行うのに使います。
後述のクラスコンストラクター__init__()より前に自動でコールされます。
class MyClass(): def __new__( cls ) : self = super().__new__( cls ) print( "__new__() myId={}".format( id( self ))) return self
通常は親クラス(Object)のコンストラクターの実行結果を戻り値として返します。
(戻り値は必須です。)
コンストラクター__init__()
コンストラクタのー__init__()はインスタンスオブジェクトが生成された後に呼ばれます。
class MyClass(): def __init__( self ) : print( "__init__() myId={}".format( id( self ))) self.myVariable = 10
インスタンス自身を第1引数に受け取り、インスタンスの初期化などを行います。
__new__()と__init__()を呼び出してみる
実際にクラスとインスタンスを生成して__new__()と__init__()を呼び出してみます。
class MyClass(): def __new__( cls ) : self = super().__new__( cls ) print( "__new__() myId={}".format( id( self ))) return self def __init__( self ) : print( "__init__() myId={}".format( id( self ))) self.myVariable = 10 cl1 = MyClass() cl2 = MyClass()
上記の実行結果は
__new__() myId=1824388893832 __init__() myId=1824388893832 __new__() myId=1824388893640 __init__() myId=1824388893640
となり、__new__()が呼ばれ、そのあとで__init__()が呼ばれていることがわかります。
#コンストラクタ__new__ __init__
#インスタンスオブジェクトが生成される前に呼ばれます。 インスタンスオブジェクトが生成された後に呼ばれます。
__new__()の使用例
__new__()も__init__()も自動で最初に呼ばれるならどちらを使っても良いのでは?と思うこともあります。
でも__new__()でしかできないこともあるので、その例を1つ挙げておきます。
今回の例はデザインパターンの「Singleton」パターンを実装してみます。
「Singleton」パターンはシステム内でそのオブジェクトが1つしかないことを保証するデザインパターンです。
通常はクラスに対して「new」をするとそのたびにインスタンスが生成されるのですが、「Singleton」パターンはすでにそのクラスが一度でもインスタンス化されていた場合は、新たにインスタンス化せずに保持している唯一のインスタンスを返す処理です。
class mySingleton: __instance = None def __new__( cls ) : if cls.__instance is None : #クラスが1度もインスタンス化されていない時 cls.__instance = super().__new__( cls ) #クラスを生成しセーブ print( "__new__" ) return cls.__instance def __init__( self ) : print( "__init__" ) if __name__ == '__main__': cl1 = mySingleton() # __new__と__init__が呼ばれる cl2 = mySingleton() # __init__しか呼ばれない print( "cl1 Id={}".format( id( cl1 ))) print( "cl2 Id={}".format( id( cl2 )))
上記の例は__new__でクラスが1度でも生成されたかチェックを行い、されてない時のみクラスを生成します。
実行結果は
__new__ __init__ __init__ cl1 Id=1626399067336 cl1 Id=1626399067336
となり生成した複数回インスタンス化しても1つのインスタンスしか生成されていないことがわかります。
まとめ
Pythonのコンストラクターには__new__()と__init__()の2つのコンストラクターが存在します。
__new__() | __init__() |
---|---|
インスタンスオブジェクトが生成される前に呼ばれます。 | インスタンスオブジェクトが生成された後に呼ばれます。 |