「11つのPython魔法メソッド- プログラマーが知っているべき」

「プログラマーが知っておくべき11のPython魔法メソッド」

 

Pythonでは、マジックメソッドを使用して、Pythonクラスで組み込み関数の動作を模倣することができます。これらのメソッドは先頭と末尾にダブルアンダースコア(__)を持ち、そのためダンダーメソッドとも呼ばれています。

これらのマジックメソッドは、Pythonでの演算子のオーバーロードもサポートします。おそらくこれの具体例を見たことがあるでしょう。2つの整数に乗算演算子*を使用すると、その積が得られます。文字列と整数kを使用すると、文字列がk回繰り返されます:

 >>> 3 * 412>>> 'code' * 3'codecodecode'

 

この記事では、単純な2次元ベクトルVector2Dクラスを作成することで、Pythonのマジックメソッドを探求します。

おそらくよく知っているであろうメソッドから始め、徐々により便利なマジックメソッドに進んでいきます。

さあ、いくつかのマジックメソッドを書き始めましょう! 

 

1. __init__

 

次のようなVector2Dクラスを考えてみましょう:

class Vector2D:    pass

 

クラスを作成してオブジェクトをインスタンス化すると、次のように属性を追加できます:obj_name.attribute_name = value

ただし、手動で作成するインスタンスごとに属性を追加する代わりに(もちろん全く興味深くない!)、オブジェクトをインスタンス化する際にこれらの属性を初期化する方法が必要です。

そのために__init__メソッドを定義することができます。以下のように、Vector2Dクラスのために__init__メソッドを定義しましょう:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = yv = Vector2D(3, 5)

 

2. __repr__

 

インスタンス化したオブジェクトを検査や出力しようとすると、役に立つ情報が得られません。

v = Vector2D(3, 5)print(v)

 

出力 >>> <__main__.Vector2D object at 0x7d2fcfaf0ac0>

 

このため、オブジェクトの文字列表現を追加する必要があります。これを行うには、__repr__メソッドを以下のように追加します:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"v = Vector2D(3, 5)print(v)

 

出力 >>> Vector2D(x=3, y=5)

 

__repr__には、クラスのインスタンスを作成するために必要なすべての属性と情報が含まれるべきです。 __repr__ メソッドは通常、デバッグのために使用されます。

 

3. __str__

 

__str__もオブジェクトの文字列表現を追加するために使用されます。一般的に、__str__メソッドはクラスのエンドユーザーに情報を提供するために使用されます。

クラスに__str__メソッドを追加しましょう:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __str__(self):        return f"Vector2D(x={self.x}, y={self.y})"v = Vector2D(3, 5)print(v)

 

出力 >>> Vector2D(x=3, y=5)

 

__str__の実装がない場合、__repr__にフォールバックします。したがって、作成するすべてのクラスには、最小限でも__repr__メソッドを追加する必要があります。

 

4. __eq__

 

次に、Vector2Dクラスの任意の2つのオブジェクトの等価性をチェックするメソッドを追加しましょう。2つのベクトルオブジェクトのx座標とy座標が同じ場合、等しいとみなされます。

同じ値のxとyを持つ2つのVector2Dオブジェクトを作成し、等しいかどうかを比較します:

v1 = Vector2D(3, 5)v2 = Vector2D(3, 5)print(v1 == v2)

 

結果はFalseです。デフォルトでは、比較はメモリ内のオブジェクトIDの等価性をチェックします。

出力 >>> False

 

等価性のチェックに__eq__メソッドを追加しましょう:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"    def __eq__(self, other):        return self.x == other.x and self.y == other.y

 

等価性のチェックは、今度は期待どおりに動作するはずです:

v1 = Vector2D(3, 5)v2 = Vector2D(3, 5)print(v1 == v2)

 

出力 >>> True 

 

5. __len__

 

Pythonの組み込み関数len()を使用すると、組み込みのイテラブルの長さを計算することができます。例えば、ベクトルの場合、長さはベクトルが含んでいる要素数を返すべきです。

したがって、Vector2Dクラスに__len__メソッドを追加しましょう:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"    def __len__(self):        return 2v = Vector2D(3, 5)print(len(v))

 

Vector2Dクラスのすべてのオブジェクトは長さ2です:

出力 >>> 2

 

6. __add__

 

次に、ベクトルに対して行う一般的な操作について考えましょう。2つのベクトルを追加および減算するためのマジックメソッドを追加しましょう。

ベクトルオブジェクトを直接追加しようとすると、エラーが発生します。そのため、__add__メソッドを追加する必要があります:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"    def __add__(self, other):        return Vector2D(self.x + other.x, self.y + other.y)

 

以下のようにして任意の2つのベクトルを追加できます:

v1 = Vector2D(3, 5)v2 = Vector2D(1, 2)result = v1 + v2print(result)

 

出力 >>> Vector2D(x=4, y=7)

 

7. __sub__

 

次に、Vector2Dクラスの任意の2つのオブジェクト間の差を計算する__sub__メソッドを追加しましょう:

class Vector2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f"Vector2D(x={self.x}, y={self.y})"
    def __sub__(self, other):
        return Vector2D(self.x - other.x, self.y - other.y)

 

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
result = v1 - v2
print(result)

 

出力 >>> Vector2D(x=2, y=3)

 

8. __mul__

 

オブジェクト間の乗算を定義するために、__mul__メソッドを定義することもできます。

以下のような操作を実装します。

  • スカラーの乗算: ベクトルのスカラー倍
  • 内積: 2つのベクトルのドット積
class Vector2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f"Vector2D(x={self.x}, y={self.y})"
    def __mul__(self, other):
        # スカラーの乗算
        if isinstance(other, (int, float)):
            return Vector2D(self.x * other, self.y * other)
        # 内積
        elif isinstance(other, Vector2D):
            return self.x * other.x + self.y * other.y
        else:
            raise TypeError("Unsupported operand type for *")

 

これで、いくつかの例を見て__mul__メソッドがどのように機能するか確認しましょう。

v1 = Vector2D(3, 5)
v2 = Vector2D(1, 2)
# スカラーの乗算
result1 = v1 * 2
print(result1)
# 内積
result2 = v1 * v2
print(result2)

 

出力 >>> Vector2D(x=6, y=10) 13

 

9. __getitem__

 

__getitem__マジックメソッドを使用すると、オブジェクトにインデックスを付けて、熟知の角括弧 [ ] 構文を使って属性または属性のスライスにアクセスできます。

Vector2Dクラスのオブジェクト v に対して:

  • v[0]: x座標
  • v[1]: y座標

インデックスでアクセスしようとすると、エラーが発生します:

v = Vector2D(3, 5)
print(v[0], v[1])

 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
----> 1 print(v[0], v[1])
TypeError: 'Vector2D' object is not subscriptable

 

__getitem__メソッドを実装しましょう:

class Vector2D:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return f"Vector2D(x={self.x}, y={self.y})"
    def __getitem__(self, key):
        if key == 0:
            return self.x
        elif key == 1:
            return self.y
        else:
            raise IndexError("Index out of range")

 

これで、次のように要素にインデックスを使用してアクセスできます:

v = Vector2D(3, 5)
print(v[0])
print(v[1])

 

出力 >>> 3 5

 

10. __call__

 

__call__メソッドを実装することで、オブジェクトを関数のように呼び出すことができます。

Vector2Dクラスでは、与えられた係数でベクトルをスケーリングするために__call__を実装することができます:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y         def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"    def __call__(self, scalar):        return Vector2D(self.x * scalar, self.y * scalar)

 

したがって、3を呼び出すと、係数3でスケーリングされたベクトルが得られます:

v = Vector2D(3, 5)result = v(3)print(result)

 

出力 >>> Vector2D(x=9, y=15)

 

11. __getattr__

 

__getattr__メソッドは、オブジェクトの特定の属性の値を取得するために使用されます。

この例では、__getattr__ダンダーメソッドを追加して、ベクトルの大きさ(L2ノルム)を計算する方法を追加できます:

class Vector2D:    def __init__(self, x, y):        self.x = x        self.y = y    def __repr__(self):        return f"Vector2D(x={self.x}, y={self.y})"    def __getattr__(self, name):        if name == "magnitude":            return (self.x ** 2 + self.y ** 2) ** 0.5        else:            raise AttributeError(f"'Vector2D'オブジェクトには'{name}'属性はありません")

 

これが期待どおりに動作するか確認しましょう:

v = Vector2D(3, 4)print(v.magnitude)

 

出力 >>> 5.0

 

結論

 

このチュートリアルでは以上です!組み込み関数の動作を模倣するためにクラスにマジックメソッドを追加する方法を学びました。

いくつかの便利なマジックメソッドについて説明しましたが、これは完全なリストではありません。さらに理解を深めるために、自分の選んだPythonクラスを作成し、必要な機能に応じてマジックメソッドを追加してみてください。コーディングを楽しんでください!

[Bala Priya C](https://twitter.com/balawc27)はインド出身の開発者兼技術ライターです。彼女は数学、プログラミング、データサイエンス、コンテンツ作成の交差点での仕事が好きです。彼女の関心と専門分野にはDevOps、データサイエンス、自然言語処理が含まれます。彼女は読書、執筆、コーディング、そしてコーヒーを楽しみます!現在、彼女はチュートリアル、ハウツーガイド、意見記事などを執筆し、開発者コミュニティと彼女の知識を共有することに取り組んでいます。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

人工知能

ジョナサン・ダムブロット、Cranium AIのCEO兼共同創設者- インタビューシリーズ

ジョナサン・ダムブロットは、Cranium AIのCEO兼共同創業者ですCranium AIは、サイバーセキュリティおよびデータサイエンスチ...

人工知能

「サティスファイラボのCEO兼共同創設者、ドニー・ホワイト- インタビューシリーズ」

2016年に設立されたSatisfi Labsは、会話型AI企業のリーディングカンパニーです早期の成功は、ニューヨーク・メッツ、メイシ...

機械学習

3つの質問:大規模言語モデルについて、Jacob Andreasに聞く

CSAILの科学者は、最新の機械学習モデルを通じた自然言語処理の研究と、言語が他の種類の人工知能をどのように高めるかの調査...

人工知能

「クリス・サレンス氏、CentralReachのCEO - インタビューシリーズ」

クリス・サレンズはCentralReachの最高経営責任者であり、同社を率いて、自閉症や関連する障害を持つ人々のために優れたクラ...

人工知能

Aaron Lee、Smith.aiの共同設立者兼CEO - インタビューシリーズ

アーロン・リーさんは、Smith.aiの共同創業者兼CEOであり、AIと人間の知性を組み合わせて、24時間365日の顧客エンゲージメン...

AIテクノロジー

「LXTのテクノロジーバイスプレジデント、アムル・ヌール・エルディン - インタビューシリーズ」

アムル・ヌール・エルディンは、LXTのテクノロジー担当副社長ですアムルは、自動音声認識(ASR)の文脈での音声/音響処理と機...