Python単例モード詳細init__インプリメンテーション
Djangoを使ってweb開発をしているときにこのような問題に遭遇しました.分岐スレッドを作成してタイミングよくあるサイトに登る情報を作りたいと思っています.まず、単例モードを使うことを考えましたが、Pythonの単例モードはjavaのようなstaticではなく、異なるメカニズムを使って実現する必要があります.ネット上でいくつかのブログを探して大体何が起こっているのかを理解しました.ここで私の理解を共有します.
まず、objectを継承したクラスのみが定義できるためnew__メソッドです.したがって、クラスを作成し、objectに継承させます.これにより、クラスを_new__メソッドが定義されました.
知っておくべきだがnew__メソッドが受け入れるパラメータと_init__同じですが_init__クラスインスタンスが作成された後に呼び出され、_new__メソッドはこのクラスインスタンスを作成するメソッドなので、クラスを作成するときにコンパイラが先に__を実行します.new__メソッド、再実行_init__方法.
次は_を定義します.new__方法:
一見疑問に思うかもしれませんが、その原理は実はこうです.
呼び出すたびに_new__メソッドは,一度に本クラスがインスタンス化されたオブジェクトが生成されたか否かを判断し,なければ1つを作成し,もしあれば以前に作成されたオブジェクトを返し,新しいパラメータを元のインスタンスに割り当てて更新する.
(ははは、javaの一例と似ているような気がしませんか~)
↑この行のコードは、このようなインスタンスが生成されたかどうかを判断します.
↑なければ親を生成させる
↑最終的にこのクラスに戻る_instanceインスタンス化オブジェクト.
完全なコードは次のとおりです.
最後の数行のコードはテストに使用され、出力結果は次のとおりです.
最後の3行のテスト結果に重点を置いて、私たちが新しく作成したオブジェクトJackはxiaomingをカバーして、Jackとxiaomingはこの時同じメモリを指しているので、print(jack)とprint(xiaoming)が出力した結果は同じで、最後の2行のテスト結果はもっとこの点を証明します.
以上、皆さんにお伝えした内容ですが、おかず1枚、足りないところはレンガを撮ってください(*╹▽╹*)
まず、objectを継承したクラスのみが定義できるためnew__メソッドです.したがって、クラスを作成し、objectに継承させます.これにより、クラスを_new__メソッドが定義されました.
class Student(object):
知っておくべきだがnew__メソッドが受け入れるパラメータと_init__同じですが_init__クラスインスタンスが作成された後に呼び出され、_new__メソッドはこのクラスインスタンスを作成するメソッドなので、クラスを作成するときにコンパイラが先に__を実行します.new__メソッド、再実行_init__方法.
次は_を定義します.new__方法:
def __new__(cls, name, height):
print('class.__new__called')
if not hasattr(cls, '_instance'): # hasattr(a,b) a b, cls( ) '_instance'
cls._instance = super(Student, cls).__new__(cls)
return cls._instance
一見疑問に思うかもしれませんが、その原理は実はこうです.
呼び出すたびに_new__メソッドは,一度に本クラスがインスタンス化されたオブジェクトが生成されたか否かを判断し,なければ1つを作成し,もしあれば以前に作成されたオブジェクトを返し,新しいパラメータを元のインスタンスに割り当てて更新する.
(ははは、javaの一例と似ているような気がしませんか~)
if not hasattr(cls, '_instance'):
↑この行のコードは、このようなインスタンスが生成されたかどうかを判断します.
cls._instance = super(Student, cls).__new__(cls)
↑なければ親を生成させる
return cls._instance
↑最終的にこのクラスに戻る_instanceインスタンス化オブジェクト.
完全なコードは次のとおりです.
class Student(object):
def __new__(cls, name, height):
print('class.__new__called')
if not hasattr(cls, '_instance'): # hasattr(a,b) a b, cls( ) '_instance'
cls._instance = super(Student, cls).__new__(cls)
return cls._instance
def __init__(self, name, height):
print('class,__init__called')
self.name = name
self.height = height
def __str__(self):
return 'The height of student %s is %s' %(self.name, self.height)
if __name__ == '__main__':
xiaoming = Student('xiaoming', 111)
print(xiaoming)
jack = Student('Jack', 188)
print(jack)
print(xiaoming)
print(id(xiaoming))
print(id(jack))
最後の数行のコードはテストに使用され、出力結果は次のとおりです.
class.__new__called
class,__init__called
The height of student xiaoming is 111
class.__new__called
class,__init__called
The height of student Jack is 188
The height of student Jack is 188
2746489404608
2746489404608
最後の3行のテスト結果に重点を置いて、私たちが新しく作成したオブジェクトJackはxiaomingをカバーして、Jackとxiaomingはこの時同じメモリを指しているので、print(jack)とprint(xiaoming)が出力した結果は同じで、最後の2行のテスト結果はもっとこの点を証明します.
以上、皆さんにお伝えした内容ですが、おかず1枚、足りないところはレンガを撮ってください(*╹▽╹*)