【Python】Python 〜 特殊メソッド / __xxx__ 〜

◾️はじめに

Python での class の後処理を実装する上で
今更ながら、Python での __xxx__(e.g. __init__)について
メモしておく

目次

【1】特殊メソッド (Special Methods)
【2】様々な特殊メソッド
 1)クラス
 2)文字列
 3)数値計算(演算子のオーバーロード)
 4)比較演算
 5)関数
【3】補足:class の後処理の実装
 実装案1:with ステートメントを使う方法
 実装案2:デストラクタ __del__ を使う方法

【1】特殊メソッド (Special Methods)

* クラスの中に定義しておくことで、
 Pythonの特定の構文や演算子と自動的に連動する仕組みを持ったメソッド
 => 色々な呼ばれ方がある模様

特殊メソッド (Special Methods)

* Pythonの公式ドキュメントで使われている正式な名称

マジックメソッド (Magic Methods)

* 開発者の間で非常によく使われるカジュアルな通称

ダンダーメソッド (Dunder Methods)

* 海外の開発者がよく使う表現
* Double Underscore(2つのアンダースコア)を略して「ダンダー(Dunder)」
* __init__ は「ダンダー・イニット」

【2】様々な特殊メソッド

1)クラス

* クラス内で使う
Methods Explanations
__init__ インスタンス化(Class())の時に自動でコールされる
__del__ デストラクタ(destructor)。オブジェクトへの参照がゼロになったときにコールされる
__enter__ ブロックに入る前に実行される処理を定義
__exit__ withブロックを抜けたときの処理を定義

デストラクタ(__del__ )に関する使用上の注意

* Pythonのガベージコレクションのタイミングに依存する
 => 実行のタイミングが保証されない

2)文字列

* オブジェクトを print() や str() で見やすい形式に変換するときに使う
Methods Explanations
__str__ print(obj) や str(obj) を呼び出したときの「人間向け」の文字列を定義
__repr__ 開発者向けのデバッグ用文字列を定義

3)コンテナ(リストや辞書)

* 自作クラスを、まるで配列や辞書のように扱えるようにする
Methods Explanations
__len__ len(obj) を使ったときに要素数を返す
__getitem__ obj[index] や obj[key] で値を取得できるようにする
__setitem__ obj[index] = value で値を代入できるようにする
__contains__ if item in obj: という所属判定を使えるようにする

3)数値計算(演算子のオーバーロード)

* 自作のクラス同士を + や - で計算できるようにする
Methods Explanations
__add__ + 演算子(足し算)の挙動を定義
__sub__ - 演算子(引き算)の挙動を定義
__mul__ * 演算子(掛け算)の挙動を定義

4)比較演算

* オブジェクト同士の大きさを比較できるようにする
Methods Explanations
__eq__ ==(等しい)の判定を定義
__lt__ <(未満)の判定を定義
__gt__ >(より大きい)の判定を定義

5)関数

* オブジェクト自体を関数のように実行できるようにする
Methods Explanations
__call___ obj() のように、インスタンスにカッコをつけて実行したときの処理を定義

【3】補足:class の後処理の実装

当初の目的のclass の後処理についてもメモしておく

実装案1:with ステートメントを使う方法

class ManagedResource:
    def __enter__(self):
        print("リソースを確保しました")
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("リソースを解放しました(後処理)")

# 使用例
with ManagedResource() as resource:
    print("処理を実行中...")

実装案2:デストラクタ del を使う方法

class MyClass:
    def __init__(self):
        print("インスタンスが生成されました")
        
    def __del__(self):
        print("インスタンスが破棄されます(後処理)")

# 使用例
obj = MyClass()
del obj  # ここで明示的に削除、またはプログラム終了時に実行

関連記事

Python ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2014/08/07/231242
Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537