テクノロジー 開発 非公開: Python のマジック メソッドとは何か、およびその使用方法

Python のマジック メソッドとは何か、およびその使用方法

Python のあまり知られていないものの貴重な機能の 1 つは、オブジェクトにマジック メソッドを実装できる機能です。魔法のメソッドを使用すると、直感的で理解しやすい、よりクリーンなコードを作成できます。

マジック メソッドを使用すると、より Python らしい方法でオブジェクトと対話するためのインターフェイスを作成できます。この記事では、マジック メソッドを紹介し、それを作成するためのベスト プラクティスについて説明し、遭遇する一般的なマジック メソッドについて説明します。

Python のマジック メソッドとは何か、およびその使用方法
Python のマジック メソッドとは何か、およびその使用方法

魔法のメソッドとは何ですか?

マジック メソッドは、一般的な操作が Python オブジェクトに対して実行されたときに Python オブジェクトがどのように動作するかを定義する Python メソッドです。これらのメソッドは、メソッド名の前後に二重アンダースコアを使用して明確に定義されます。

その結果、これらは一般に、 ダブル アンダー スコアなどのダンダーメソッドと呼ばれます。すでに遭遇したことのある一般的なダンダー メソッドは、クラス コンストラクターの定義に使用される __init__() メソッドです。

通常、ダンダー メソッドはコード内で直接呼び出すことを想定していません。むしろ、プログラムの実行中にインタプリタによって呼び出されます。

なぜ魔法の方法が役立つのでしょうか?

マジック メソッドは、Python のオブジェクト指向プログラミングにおける有用な概念です。これらを使用して、カスタム データ型が一般的な組み込み操作で使用されるときの動作を指定します。これらの操作には次のものが含まれます。

🟢 算術演算

🟢 比較演算

🟢 ライフサイクル操作

🟢 表現操作

次のセクションでは、上記のすべてのカテゴリで使用された場合にアプリケーションがどのように動作するかを定義するマジック メソッドを実装する方法について説明します。

マジックメソッドを定義する方法

前述したように、マジック メソッドはオブジェクトの動作を指定します。したがって、それらはオブジェクトのクラスの一部として定義されます。これらはオブジェクト クラスの一部であるため、オブジェクト自体への参照である self 最初の引数として受け取ります。

インタプリタによる呼び出し方法に応じて、追加の引数を受け取ることができます。また、名前の前後に 2 つのアンダースコアを付けて明確に定義されます。

実装

私たちがこれまで議論してきたことの多くは理論的で抽象的なように思えます。このセクションでは、単純な Rectangle クラスを実装します。

このクラスには長さと幅のプロパティがあります。 __init__ メソッドを使用すると、インスタンス化時にこれらのプロパティを指定できます。さらに、 == < および > 演算子を使用して、異なる四角形を比較して、別の四角形と等しいか、小さいか、大きいかを確認できます。最後に、四角形は意味のある文字列表現を提供できる必要があります。

コーディング環境のセットアップ

このチュートリアルを進めるには、Python ランタイム環境が必要です。ローカルのものを使用することも、オンラインの Python コンパイラーを使用することもできます。

Rectangle クラスの作成

まず、Rectangle クラスを定義することから始めましょう。

 class Rectangle:
    pass 

コンストラクターメソッドの作成

次に、最初のマジック メソッドであるクラス コンストラクター メソッドを作成しましょう。このメソッドは高さと幅を取得し、それらをクラス インスタンスの属性として保存します。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width 

文字列表現のためのマジックメソッドの作成

次に、オブジェクトを表す人間が読める文字列をクラスで生成できるようにするメソッドを作成します。このメソッドは、 Rectangle クラスのインスタンスを引数として渡す str() 関数を呼び出すたびに呼び出されます。このメソッドは、 print 関数などの文字列引数を期待する関数を呼び出すときにも呼び出されます。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

__str__() メソッドは、オブジェクトを表す文字列を返す必要があります。この場合、 Rectangle(<height>, <width>) 形式の文字列を返します。ここで、高さと幅は、保存されている長方形の寸法です。

比較演算用のマジック メソッドの作成

次に、等しい、より小さい、より大きい演算のための比較演算子を作成します。これは演算子のオーバーロードと呼ばれます。これらを作成するには、マジック メソッド __eq__ __lt__ __gt__ をそれぞれ使用します。これらのメソッドは、長方形の面積を比較した後、ブール値を返します。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

    def __eq__(self, other):
        """ Checking for equality """
        return self.height * self.width == other.height * other.width

    def __lt__(self, other):
        """ Checking if the rectangle is less than the other one """
        return self.height * self.width < other.height * other.width

    def __gt__(self, other):
        """ Checking if the rectage is greater than the other one """
        return self.height * self.width > other.height * other.width

ご覧のとおり、これらのメソッドは 2 つのパラメーターを受け取ります。 1 つ目は現在の四角形で、2 つ目は比較対象の他の値です。この値は、別の Rectangle インスタンスまたはその他の値にすることができます。比較方法のロジックと、比較が true を返す条件は完全にユーザー次第です。

一般的な魔法の方法

次のセクションでは、あなたが遭遇して使用する一般的な魔法の方法について説明します。

#1. 算術演算

993ショット_ソ
993ショット_ソ

算術マジック メソッドは、クラスのインスタンスが算術記号の左側に配置されたときに呼び出されます。このメソッドは 2 つの引数を指定して呼び出されます。最初の引数はインスタンスへの参照です。 2 番目の値は、記号の右側にあるオブジェクトです。方法と標識は次のとおりです。

名前 方法 サイン 説明
追加 __add__ + 追加を実装します。
引き算 __sub__ 減算を実装します。
乗算 __mul__ * 乗算を実装します
分割 __div__ / 分割を実装します。
フロア区分 __フロアディビジョン__ // フロア分割を実装します。

#2. 比較演算

293ショット_ソ
293ショット_ソ

算術マジック メソッドと同様に、これらのメソッドは、定義されているクラスのインスタンスが比較演算子の左側に配置されたときに呼び出されます。また、算術マジック メソッドと同様に、これらは 2 つのパラメータを使用して呼び出されます。 1 つ目はオブジェクトのインスタンスへの参照です。 2 番目は、記号の右側の値への参照です。

名前 方法 サイン 説明
未満 __lt__ < 小なり比較を実装します
より大きい __gt__ > 大なり比較を実装します
に等しい __eq__ == 等しい比較を実装します
以下 __le__ >= 以下の比較を実装します
以上 __ge__ <= 以上の比較を実装します。

#3. ライフサイクル操作

739ショット_ソ
739ショット_ソ

これらのメソッドは、インスタンス化や削除など、オブジェクトのさまざまなライフサイクル メソッドに応じて呼び出されます。コンストラクター __init __ がこのカテゴリに分類されます。このカテゴリの一般的な方法を次の表に示します。

名前 方法 説明
コンストラクタ __init__ このメソッドは、定義されているクラスのオブジェクトが削除されるたびに呼び出されます。これを使用して、開いたファイルを閉じるなどのクリーンアップ操作を実行できます。
削除 __del__ このメソッドは、定義されているクラスのオブジェクトが削除されるたびに呼び出されます。これを使用して、開いたファイルを閉じるなどのクリーンアップ操作を実行できます。
新しい __新しい__ __new__ メソッドは、指定されたクラスのオブジェクトがインスタンス化されるときに最初に呼び出されます。このメソッドはコンストラクターの前に呼び出され、クラスと追加の引数を受け取ります。クラスのインスタンスを返します。ほとんどの場合、あまり役に立ちませんが、 ここで 詳しく説明します。

#4. 表現操作

44ショット_ソ
44ショット_ソ
名前 方法 説明
Str __str__ 人間が判読できるオブジェクトの文字列表現を返します。このメソッドは、クラスのインスタンスを引数として渡して str() 関数を呼び出すときに呼び出されます。これは、インスタンスを print() 関数と format() 関数に渡すときにも呼び出されます。これは、アプリケーションのエンドユーザーが理解できる文字列を提供することを目的としています。
担当者 __repr__ 開発者が使用するオブジェクトの文字列表現を返します。理想的には、返される文字列は、その文字列だけからオブジェクトの同一のインスタンスを構築できるように情報が豊富である必要があります。

マジック メソッドを作成するためのベスト プラクティス

マジック メソッドは驚くべきものであり、コードを簡素化します。ただし、使用する場合は次のことに留意することが重要です。

  • 使用は慎重に – クラスにマジック メソッドを実装しすぎると、コードが理解しにくくなります。必須のもののみを実装するように制限してください。
  • __setatrr__ や __getattr__ などのメソッドを使用する前に、そのパフォーマンスへの影響を必ず理解してください。
  • 他の開発者がマジック メソッドの動作を正確に把握できるように、マジック メソッドの動作を文書化します。これにより、必要に応じてそれらを使用したりデバッグしたりすることが容易になります。

最後の言葉

今回は組み込み演算で使えるクラスの作り方としてマジックメソッドを紹介しました。また、それらがどのように定義されるかについて説明し、マジック メソッドが実装されたクラスの例についても説明しました。次に、留意すべきいくつかのベスト プラクティスを共有する前に、使用する可能性が高く必要となるさまざまな方法について説明しました。

次に、Python で Counter クラスを実装する方法を学習するとよいでしょう。

「 Python のマジック メソッドとは何か、およびその使用方法」についてわかりやすく解説!絶対に観るべきベスト2動画

Python(パイソン)関数(メソッド)とラムダ式(簡易な関数)の基礎をVSCodeエディターで解説
14-IRISでPythonを使ってみよう-ObjectScriptのメソッドを作成してPythonから呼び出す

Python のあまり知られていないものの貴重な機能の 1 つは、オブジェクトにマジック メソッドを実装できる機能です。魔法のメソッドを使用すると、直感的で理解しやすい、よりクリーンなコードを作成できます。

マジック メソッドを使用すると、より Python らしい方法でオブジェクトと対話するためのインターフェイスを作成できます。この記事では、マジック メソッドを紹介し、それを作成するためのベスト プラクティスについて説明し、遭遇する一般的なマジック メソッドについて説明します。

Python のマジック メソッドとは何か、およびその使用方法
Python のマジック メソッドとは何か、およびその使用方法

魔法のメソッドとは何ですか?

マジック メソッドは、一般的な操作が Python オブジェクトに対して実行されたときに Python オブジェクトがどのように動作するかを定義する Python メソッドです。これらのメソッドは、メソッド名の前後に二重アンダースコアを使用して明確に定義されます。

その結果、これらは一般に、 ダブル アンダー スコアなどのダンダーメソッドと呼ばれます。すでに遭遇したことのある一般的なダンダー メソッドは、クラス コンストラクターの定義に使用される __init__() メソッドです。

通常、ダンダー メソッドはコード内で直接呼び出すことを想定していません。むしろ、プログラムの実行中にインタプリタによって呼び出されます。

なぜ魔法の方法が役立つのでしょうか?

マジック メソッドは、Python のオブジェクト指向プログラミングにおける有用な概念です。これらを使用して、カスタム データ型が一般的な組み込み操作で使用されるときの動作を指定します。これらの操作には次のものが含まれます。

🟢 算術演算

🟢 比較演算

🟢 ライフサイクル操作

🟢 表現操作

次のセクションでは、上記のすべてのカテゴリで使用された場合にアプリケーションがどのように動作するかを定義するマジック メソッドを実装する方法について説明します。

マジックメソッドを定義する方法

前述したように、マジック メソッドはオブジェクトの動作を指定します。したがって、それらはオブジェクトのクラスの一部として定義されます。これらはオブジェクト クラスの一部であるため、オブジェクト自体への参照である self 最初の引数として受け取ります。

インタプリタによる呼び出し方法に応じて、追加の引数を受け取ることができます。また、名前の前後に 2 つのアンダースコアを付けて明確に定義されます。

実装

私たちがこれまで議論してきたことの多くは理論的で抽象的なように思えます。このセクションでは、単純な Rectangle クラスを実装します。

このクラスには長さと幅のプロパティがあります。 __init__ メソッドを使用すると、インスタンス化時にこれらのプロパティを指定できます。さらに、 == < および > 演算子を使用して、異なる四角形を比較して、別の四角形と等しいか、小さいか、大きいかを確認できます。最後に、四角形は意味のある文字列表現を提供できる必要があります。

コーディング環境のセットアップ

このチュートリアルを進めるには、Python ランタイム環境が必要です。ローカルのものを使用することも、オンラインの Python コンパイラーを使用することもできます。

Rectangle クラスの作成

まず、Rectangle クラスを定義することから始めましょう。

 class Rectangle:
    pass 

コンストラクターメソッドの作成

次に、最初のマジック メソッドであるクラス コンストラクター メソッドを作成しましょう。このメソッドは高さと幅を取得し、それらをクラス インスタンスの属性として保存します。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width 

文字列表現のためのマジックメソッドの作成

次に、オブジェクトを表す人間が読める文字列をクラスで生成できるようにするメソッドを作成します。このメソッドは、 Rectangle クラスのインスタンスを引数として渡す str() 関数を呼び出すたびに呼び出されます。このメソッドは、 print 関数などの文字列引数を期待する関数を呼び出すときにも呼び出されます。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

__str__() メソッドは、オブジェクトを表す文字列を返す必要があります。この場合、 Rectangle(<height>, <width>) 形式の文字列を返します。ここで、高さと幅は、保存されている長方形の寸法です。

比較演算用のマジック メソッドの作成

次に、等しい、より小さい、より大きい演算のための比較演算子を作成します。これは演算子のオーバーロードと呼ばれます。これらを作成するには、マジック メソッド __eq__ __lt__ __gt__ をそれぞれ使用します。これらのメソッドは、長方形の面積を比較した後、ブール値を返します。

 class Rectangle:
    def __init__(self, height, width):
        self.height = height
        self.width = width

    def __str__(self):
        return f'Rectangle({self.height}, {self.width})'

    def __eq__(self, other):
        """ Checking for equality """
        return self.height * self.width == other.height * other.width

    def __lt__(self, other):
        """ Checking if the rectangle is less than the other one """
        return self.height * self.width < other.height * other.width

    def __gt__(self, other):
        """ Checking if the rectage is greater than the other one """
        return self.height * self.width > other.height * other.width

ご覧のとおり、これらのメソッドは 2 つのパラメーターを受け取ります。 1 つ目は現在の四角形で、2 つ目は比較対象の他の値です。この値は、別の Rectangle インスタンスまたはその他の値にすることができます。比較方法のロジックと、比較が true を返す条件は完全にユーザー次第です。

一般的な魔法の方法

次のセクションでは、あなたが遭遇して使用する一般的な魔法の方法について説明します。

#1. 算術演算

993ショット_ソ
993ショット_ソ

算術マジック メソッドは、クラスのインスタンスが算術記号の左側に配置されたときに呼び出されます。このメソッドは 2 つの引数を指定して呼び出されます。最初の引数はインスタンスへの参照です。 2 番目の値は、記号の右側にあるオブジェクトです。方法と標識は次のとおりです。

名前 方法 サイン 説明
追加 __add__ + 追加を実装します。
引き算 __sub__ 減算を実装します。
乗算 __mul__ * 乗算を実装します
分割 __div__ / 分割を実装します。
フロア区分 __フロアディビジョン__ // フロア分割を実装します。

#2. 比較演算

293ショット_ソ
293ショット_ソ

算術マジック メソッドと同様に、これらのメソッドは、定義されているクラスのインスタンスが比較演算子の左側に配置されたときに呼び出されます。また、算術マジック メソッドと同様に、これらは 2 つのパラメータを使用して呼び出されます。 1 つ目はオブジェクトのインスタンスへの参照です。 2 番目は、記号の右側の値への参照です。

名前 方法 サイン 説明
未満 __lt__ < 小なり比較を実装します
より大きい __gt__ > 大なり比較を実装します
に等しい __eq__ == 等しい比較を実装します
以下 __le__ >= 以下の比較を実装します
以上 __ge__ <= 以上の比較を実装します。

#3. ライフサイクル操作

739ショット_ソ
739ショット_ソ

これらのメソッドは、インスタンス化や削除など、オブジェクトのさまざまなライフサイクル メソッドに応じて呼び出されます。コンストラクター __init __ がこのカテゴリに分類されます。このカテゴリの一般的な方法を次の表に示します。

名前 方法 説明
コンストラクタ __init__ このメソッドは、定義されているクラスのオブジェクトが削除されるたびに呼び出されます。これを使用して、開いたファイルを閉じるなどのクリーンアップ操作を実行できます。
削除 __del__ このメソッドは、定義されているクラスのオブジェクトが削除されるたびに呼び出されます。これを使用して、開いたファイルを閉じるなどのクリーンアップ操作を実行できます。
新しい __新しい__ __new__ メソッドは、指定されたクラスのオブジェクトがインスタンス化されるときに最初に呼び出されます。このメソッドはコンストラクターの前に呼び出され、クラスと追加の引数を受け取ります。クラスのインスタンスを返します。ほとんどの場合、あまり役に立ちませんが、 ここで 詳しく説明します。

#4. 表現操作

44ショット_ソ
44ショット_ソ
名前 方法 説明
Str __str__ 人間が判読できるオブジェクトの文字列表現を返します。このメソッドは、クラスのインスタンスを引数として渡して str() 関数を呼び出すときに呼び出されます。これは、インスタンスを print() 関数と format() 関数に渡すときにも呼び出されます。これは、アプリケーションのエンドユーザーが理解できる文字列を提供することを目的としています。
担当者 __repr__ 開発者が使用するオブジェクトの文字列表現を返します。理想的には、返される文字列は、その文字列だけからオブジェクトの同一のインスタンスを構築できるように情報が豊富である必要があります。

マジック メソッドを作成するためのベスト プラクティス

マジック メソッドは驚くべきものであり、コードを簡素化します。ただし、使用する場合は次のことに留意することが重要です。

  • 使用は慎重に – クラスにマジック メソッドを実装しすぎると、コードが理解しにくくなります。必須のもののみを実装するように制限してください。
  • __setatrr__ や __getattr__ などのメソッドを使用する前に、そのパフォーマンスへの影響を必ず理解してください。
  • 他の開発者がマジック メソッドの動作を正確に把握できるように、マジック メソッドの動作を文書化します。これにより、必要に応じてそれらを使用したりデバッグしたりすることが容易になります。

最後の言葉

今回は組み込み演算で使えるクラスの作り方としてマジックメソッドを紹介しました。また、それらがどのように定義されるかについて説明し、マジック メソッドが実装されたクラスの例についても説明しました。次に、留意すべきいくつかのベスト プラクティスを共有する前に、使用する可能性が高く必要となるさまざまな方法について説明しました。

次に、Python で Counter クラスを実装する方法を学習するとよいでしょう。

「 Python のマジック メソッドとは何か、およびその使用方法」についてわかりやすく解説!絶対に観るべきベスト2動画

Python(パイソン)関数(メソッド)とラムダ式(簡易な関数)の基礎をVSCodeエディターで解説
14-IRISでPythonを使ってみよう-ObjectScriptのメソッドを作成してPythonから呼び出す