この記事では、主に Python の __init__、__new__、__call__ メソッドに関する関連情報をサンプル コードを通じて詳細に紹介します。この記事は、必要なすべての人にとって参照と学習の価値があります。 . 以下のエディターで見てみましょう。
前書き
この記事では主に Python の __init__、__new__、__call__ メソッドに関連する内容を紹介し、参考と学習のために共有します。以下で説明することはあまりありません。詳細 はじめに:
すべてのものには、作成、使用、消滅までのプロセスがあります。プログラミング言語のオブジェクト指向プログラミング モデルでは、オブジェクトも同様の運命をたどります。さまざまな段階がさまざまな段階で構成されます。メソッド (ロール) が実行を担当します。
クラスを定義する場合、最も一般的に使用されるメソッドは __init__ メソッドですが、__new__ と __call__ はそれほど頻繁には使用されません。この記事は、これら 3 つのメソッドの正しい使用法と適用シナリオを説明することを目的としています。
古いスタイルのクラスは Python2 の概念であり、古いスタイルのクラスを使用する人はもうほとんどいないため、この記事では Python の新しいスタイルのクラスと古いスタイルのクラスについてはあまり説明しません。クラスはオブジェクトを明示的に継承する必要があります。Python3 では、新しいスタイルのクラスのみがデフォルトでオブジェクトを継承するため、明示的に指定する必要はありません。この記事のコードはすべて Python3 に基づいています。
__init__ メソッド
__init__ メソッドは、システムがこのメソッドを実行する前に、実際にはすでに存在しています。それ以外の場合、他に何が初期化されるでしょうか。まず例を見てみましょう:
# class A(object): python2 必须显示地继承object class A: def __init__(self): print("__init__ ") super(A, self).__init__() def __new__(cls): print("__new__ ") return super(A, cls).__new__(cls) def __call__(self): # 可以定义任意参数 print('__call__ ') A()
Output
__new__ __init__
出力結果から、最初に __new__ メソッドが呼び出され、インスタンス オブジェクトを返し、次に __init__ が呼び出されます。 __call__ メソッドはまだ呼び出されていません。最初に最初の 2 つのメソッドについて説明します。
def __init__(self): print("__init__ ") print(self) super(A, self).__init__() def __new__(cls): print("__new__ ") self = super(A, cls).__new__(cls) print(self) return self
出力結果から、__new__ メソッドを呼び出します。戻り値はクラスのインスタンス オブジェクトです。このインスタンス オブジェクトは、インスタンス オブジェクトが正しく初期化されるように、__init__ メソッドで定義された self パラメーターに渡されます。
__new__ メソッドが値を返さない (または None を返す) 場合、__init__ は呼び出されません。これは、インスタンス オブジェクトが作成されておらず、init を呼び出すことは無意味であるためです。また、Python では次のように規定されています。 、__init__ は None 値のみを返すことができ、それ以外の場合はエラーが報告されます。これは誰でも試すことができます。
__new__ <__main__.A object at 0x1007a95f8> __init__ <__main__.A object at 0x1007a95f8>
さらに、self を除く __init__ メソッドで定義されたパラメータは、__new__ のパラメータと同じになります。メソッド cls パラメータ以外のパラメータは、一貫性があるか同等である必要があります。
def __init__(self, a, b): self.a = a self.b = b super(A, self).__init__()
__new__ メソッド
一般的に、その方法を正確に知っていない限り、このメソッドはオブジェクトを作成するためのコンストラクターとして使用されます。はい、ファクトリーです。インスタンスオブジェクトの生成専用の関数。有名なデザイン パターンの 1 つであるシングルトン パターンは、この方法で実装できます。フレームワーク レベルのコードを自分で作成するときに使用することもできます。また、マイクロ Web フレームワーク Bootle などのオープン ソース コードからそのアプリケーション シナリオを見つけることもできます。
class B: def __init__(self, *args, **kwargs): print("init", args, kwargs) def __new__(cls, *args, **kwargs): print("new", args, kwargs) return super().__new__(cls) B(1, 2, 3) # 输出 new (1, 2, 3) {} init (1, 2, 3) {}
このコードは https://github.com/bottlepy/bottle/blob/release-0.6/bottle.py からのものです
これは、インスタンスの __new__ メソッドを通じてシングルトン モードを実装する方法です。オブジェクトが存在する場合は、インスタンスを直接返します。まだ存在しない場合は、最初にインスタンスを作成してから返します。もちろん、Python の禅では、シングルトン パターンを実装する方法は複数あります:
__call__ メソッド
__call__ メソッドについては、最初に概念について言及する必要があります。それは、呼び出し可能なオブジェクト (呼び出し可能オブジェクト)、通常のカスタム関数、組み込み関数、およびクラスです。は呼び出し可能なオブジェクトですが、括弧 () のペアに適用できるオブジェクトはすべて呼び出し可能なオブジェクトと呼ぶことができます。オブジェクトが呼び出し可能なオブジェクトかどうかを判断するには、関数 callable が class_ に実装されている場合に使用できます。 _call__ メソッドを使用すると、インスタンス オブジェクトも呼び出し可能なオブジェクトになります。元の例に戻りましょう。
class BaseController(object): _singleton = None def __new__(cls, *a, **k): if not cls._singleton: cls._singleton = object.__new__(cls, *a, **k) return cls._singleton
a はインスタンス オブジェクトであり、呼び出し可能なオブジェクトでもあるため、関数のように呼び出すことができます。試してください:
a() # __call__
很神奇不是,实例对象也可以像函数一样作为可调用对象来用,那么,这个特点在什么场景用得上呢?这个要结合类的特性来说,类可以记录数据(属性),而函数不行(闭包某种意义上也可行),利用这种特性可以实现基于类的装饰器,在类里面记录状态,比如,下面这个例子用于记录函数被调用的次数:
class Counter: def __init__(self, func): self.func = func self.count = 0 def __call__(self, *args, **kwargs): self.count += 1 return self.func(*args, **kwargs) @Counter def foo(): pass for i in range(10): foo() print(foo.count) # 10
在 Bottle 中也有 call 方法 的使用案例,另外,stackoverflow 也有一些关于 call 的实践例子,推荐看看,如果你的项目中,需要更加抽象化、框架代码,那么这些高级特性往往能发挥出它作用。
总结
以上がPython の 3 つのメソッド __init__、__new__、__call__ の簡単な紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。