構築 (__new__) と初期化 (__init__)
前の記事の内容から、クラスを定義するときに、オブジェクトをインスタンス化するときに __init__(self) メソッドを使用して属性を設定することがよくあることがすでにわかりました。たとえば、次の例は次のとおりです。
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- class User(object): def __init__(self, name, age): self.name = name; self.age = age; user=User('两点水',23)
実際、クラスの作成プロセスは 2 つのステップに分かれており、1 つはクラスのオブジェクトの作成で、もう 1 つはクラスの初期化です。 __new__ はクラスを作成してこのクラスのインスタンスを返すために使用されますが、__init__ は渡されたパラメーターでインスタンスを初期化するだけです。__new__ はインスタンスの作成プロセス中に必ず呼び出されますが、__init__ は必ずしも呼び出されるとは限りません。 pickle .load を使用してインスタンスを逆シリアル化する場合、__init__ メソッドは呼び出されません。
def __new__(cls) は def __init__(self) メソッドの前に呼び出され、その機能はインスタンス オブジェクトを返すことです。もう 1 つ注意すべき点は、__new__ メソッドは常にクラスのインスタンスを返す必要があり、__init__ は None 以外の値を返すことはできないということです。
具体的な例:
#!/usr/bin/env python3 # -*- coding: UTF-8 -*- class User(object): def __new__(cls, *args, **kwargs): # 打印 __new__方法中的相关信息 print('调用了 def __new__ 方法') print(args) # 最后返回父类的方法 return super(User, cls).__new__(cls) def __init__(self, name, age): print('调用了 def __init__ 方法') self.name = name self.age = age if __name__ == '__main__': usr = User('两点水', 23)
出力を見てください。結果は次のとおりです。
调用了 def __new__ 方法 ('两点水', 23) 调用了 def __init__ 方法
出力された結果からクラス作成の流れが分かりますが、まず __new__ メソッドを呼び出してオブジェクトを作成し、パラメータを __init__ メソッドに渡してインスタンス化します。
実際、実際の開発では、クラスの作成を制御できるようにしたい場合を除き、__new__ メソッドが使用されることはほとんどありません。通常、__new__ について話すとき、すべてメタクラスが関係します。
もちろん、オブジェクトのライフサイクルが終了すると、デストラクター __del__ メソッドが呼び出されます。ただし、このメソッドは Python 自体がオブジェクトをガベージ コレクションするために使用します。