__new__

3457 ワード

一、init方法は何ですか.
Pythonを使用してオブジェクト向けのコードを書いたことがある人は、initメソッドに詳しいかもしれません.initメソッドは通常、クラスインスタンスを初期化するときに使用されます.例:
class Person(object):
    """Silly Person"""
 
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
    def __str__(self):
        return '' % (self.name, self.age)
 
if __name__ == '__main__':
    piglei = Person('piglei', 24)
    print piglei

これがinitの最も一般的な使い方です.しかしinitはクラスをインスタンス化するときに最初に呼び出される方法ではありません.Persion(name,age)のような式を用いてクラスをインスタンス化する場合,最初に呼び出される方法はnewメソッドである.
二、newの方法は何ですか.
newメソッドが受け入れるパラメータもinitと同じですが、initはクラスインスタンスの作成後に呼び出され、newメソッドはこのクラスインスタンスを作成する方法です.
class Person(object):
    """Silly Person"""
 
    def __new__(cls, name, age):
        print '__new__ called.'
        return super(Person, cls).__new__(cls, name, age)
 
    def __init__(self, name, age):
        print '__init__ called.'
        self.name = name
        self.age = age
 
    def __str__(self):
        return '' % (self.name, self.age)
 
if __name__ == '__main__':
    piglei = Person('piglei', 24)
    print piglei

実行結果:
__new__ called.
__init__ called.

このコードを実行すると、newメソッドの呼び出しはinitの前に発生することがわかります.実際にクラスをインスタンス化すると、具体的な実行ロジックは次のようになります.
1.p = Person(name, age) 2.まず、Personクラスのnewメソッドを実行するためにnameとageパラメータを使用し、このnewメソッドはPersonクラスのインスタンス(通常はsuper(Persion,cls)を返す.new(cls,......)のような方式)、3.次にこのインスタンスを用いてクラスのinitメソッドを呼び出し,前のステップでnewが生成したインスタンス,すなわちinitのselfであるため,initとnewの最も主要な違いは:1である.Initは通常、クラスインスタンスが作成された後、いくつかの属性を追加したり、追加の操作をしたりするなど、新しいインスタンスを初期化するために使用されます.これはインスタンスレベルのメソッドです.2.newは、通常、新しいインスタンスを生成するプロセスを制御するために使用される.クラスレベルのメソッドです.しかし、こんなにたくさん言って、newの最も一般的な使い方は何ですか.私たちはいつnewが必要ですか.
編集者はpythonの学習qun 740322,34を推薦する.
あなたが大牛であろうと白であろうと、転職したいのか、入行したいのかを理解して一緒に勉強することができます.スカートの中には開発ツールがあり、多くの乾物と技術資料が共有されています.
三、newの役割
Pythonの公式ドキュメントによると、newメソッドは主に、int、str、tupleなどの可変classを継承するときに、これらのクラスのインスタンス化プロセスをカスタマイズする方法を提供します.また、カスタムmetaclassを実現します.まず、最初の機能を見てみましょう.具体的にはintを例に挙げることができます.もし私たちが永遠に正数の整数タイプが必要なら、intを統合することで、このようなコードを書くことができます.
def __init__(self, value):
        super(PositiveInteger, self).__init__(self, abs(value))
 
i = PositiveInteger(-3)
print i

しかし、運行後、結果は私たちが考えているほどではなく、私たちは-3を手に入れたことに気づきます.これはintという可変のオブジェクトに対して,そのnewメソッドを再ロードしてこそカスタムの役割を果たすことができるからである.これは修正されたコードです.
def __new__(cls, value):
        return super(PositiveInteger, cls).__new__(cls, abs(value))
 
i = PositiveInteger(-3)
print i

newメソッドを再ロードすることで,必要な機能を実現した.もう1つの役割は、metaclassのカスタマイズについてです.実は私が一番早くnewに触れたのは、metaclassをカスタマイズする必要があるからですが、紙面の都合上、pythonのmetaclassとnewの関係を次にお話しします.
四、newで単例を実現する
実際,new法を理解した後,設計モードにおける単一のモード(singleton)を実現するなど,他の興味深いことをするために利用することもできる.クラスがインスタンス化されるたびに生じるプロセスはnewによって制御されるため,newメソッドを再ロードすることで,単一例モードを簡単に実現できる.
def __new__(cls):
        #      ,         ,           instance  
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance
 
obj1 = Singleton()
obj2 = Singleton()
 
obj1.attr1 = 'value1'
print obj1.attr1, obj2.attr1
print obj1 is obj2

出力結果:
True

obj 1とobj 2は同じインスタンスであることがわかります.