ホームページ >バックエンド開発 >Python チュートリアル >Python のオブジェクト作成で __new__() の後に常に __init__() が呼び出されるのはなぜですか?

Python のオブジェクト作成で __new__() の後に常に __init__() が呼び出されるのはなぜですか?

DDD
DDDオリジナル
2024-12-19 15:47:11477ブラウズ

Why is `__init__()` Always Called After `__new__()` in Python's Object Creation?

「__init__()」および「__new__()」: シーケンスと目的

「__init__()」および「__new__()」 Python のオブジェクト指向プログラミングの基本的なメソッドで、インスタンスの作成を制御するために使用されます。初期化。

「__new__()」はメモリを割り当て、クラスの新しいインスタンスを作成し、新しく作成されたオブジェクトを返します。これはインスタンスの実際の作成を担当します。

対照的に、「__init__()」は新しく作成されたインスタンスを初期化します。これは、インスタンスの属性を設定し、オブジェクトを使用できるように準備するために必要なアクションを実行する責任があります。

Python の設計では、インスタンス作成プロセスで "__new__()" の後に "__init__()" が常に呼び出されることが規定されています。 。これは、新しいインスタンスを作成した後に初期化する必要があるためです。

Flyweight パターンと "__init__()" 呼び出し

Flyweight パターンのコンテキスト内、「__new__()」の後に呼び出される「__init__()」の予期される動作について混乱するかもしれません。これは、Flyweight パターンが通常、インスタンスの作成を制御し、同じオブジェクトの複数のコピーの作成を回避するために「__new__()」を利用するためです。

サンプル コードでは、カスタムの「__new__()」メソッドを実装しています。辞書内のキーの存在に基づいてインスタンスの作成を処理します。ただし、Flyweight パターンを使用して作成される後続のインスタンスであっても、"__init__()" メソッドが 1 回だけ呼び出されるように意図している可能性があります。

なぜ "__init__()" は " の後に常に呼び出されますか" __new__()"?

この動作の理由は、Python のオブジェクト指向システムでは、作成されるすべてのインスタンスが次のようになると想定しているためです。 「__init__()」の呼び出しによって初期化されます。これはインスタンス作成プロセスの基本的な部分であり、オブジェクトが使用できるように完全に準備されていることを確認します。

代替実装

Flyweight パターンを実装し、「」の呼び出しを回避するには__init__()」を複数回実行する場合は、「__new__()」をオーバーライドする代わりにファクトリ クラスを使用する必要があります。これは、より堅牢で標準的なアプローチと考えられています。

ファクトリベースの Flyweight 実装の例を次に示します。

class FlyweightFactory:
    _cache = {}

    def __get(key):
        if key not in FlyweightFactory._cache:
            FlyweightFactory._cache[key] = Flyweight(key)
        return FlyweightFactory._cache[key]

class Flyweight:
    def __init__(self, key):
        self.key = key

この実装では、ファクトリ クラスは、キーを使用することで、複数の「__init__()」呼び出しの必要性を回避できます。

以上がPython のオブジェクト作成で __new__() の後に常に __init__() が呼び出されるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。