web-dev-qa-db-ja.com

Python-イニシャライザーとコンストラクター

__init__ function in pythonはコンストラクターではなく、イニシャライザーであり、実際には__new__関数はコンストラクターであり、違いは__init__関数は、オブジェクトの作成後に呼び出され、__new__前に呼び出されました。私は正しいですか?違いをよりよく説明できますか、なぜ両方が必要なのですか__new__および__init__

12
oridamari

本質的に、__new__はインスタンスの作成に責任があります(したがって、あなたが指摘したように、それはコンストラクターと言うのが正確かもしれません)が、__init__は確かにインスタンスの状態を初期化する方法。たとえば、次のことを考慮してください。

class A(object):

    def __new__(cls):
        return object.__new__(cls)

    def __init__(self):
        self.instance_method()

    def instance_method(self):
        print 'success!'

newA = A()

__init__は引数selfを受け取り、__new__はクラス(cls)を受け取ることに注意してください。 selfはインスタンスへの参照であるため、これは、インスタンスが渡されるため、__init__が呼び出されるまでにインスタンスがすでに作成されていることを明確に示しているはずです。インスタンスがすでに作成されているため、インスタンスメソッドを呼び出すこともできます。

2番目の質問に関しては、私の経験では__new__を使用する必要はめったにありません。確かに、より高度な手法で__new__を使用する場合もありますが、それはまれです。人々が__new__を使いたくなるかもしれない悪名高い例の1つは、シングルトンクラスの作成です(ただし、それが優れた手法であるかどうかは重要ではありません)。

良くも悪くも、基本的にインスタンス化のプロセスを制御することができ、それが特定の状況で意味するものは何でも。

8
Eithos

__init__は、オブジェクトのすでに構築されたインスタンスを最初のパラメーターとして使用して呼び出されます(通常はselfと呼ばれますが、これは単なるパラメーター名です)。

代わりに、__new__は、最初のパラメーターとしてclassを渡すことで呼び出され、インスタンスを返すことが期待されます(後で__init__に渡されます)。

これにより、たとえば__new__は、不変でIDが役割を果たさない値ベースのオブジェクトの既存のインスタンスを返すことができます。

2
6502

詳細については、 クラスのカスタマイズに関するドキュメント を検討してください。

それに応じて、これらのメソッドは次のように使用されます。オブジェクトを作成するための__new__()、およびオブジェクトをカスタマイズするための__init__()

そして6502が気づいたように、__new__は静的メソッドの特殊なケースであり、引数としてクラスを取得しますが、__init____new__によって生成されたオブジェクトを取得します

1