「Everything is an Object」、Pythonエンジニアには馴染みのある一言。何もかもクラスに書き込んで、華麗に継承し合うするのがPythonエンジニアのロマン(いたずら)と言っても過言ではない。
そのクラスの中でいつも出てくる__init__
の使い方は知ってると思いますが、他に時々見かける__xxxx__
の関数は一体なんなのか、こういう関数がいくらあるか、悩んだことはありますか?今日はよく見る__dunder__
のインスタンス生成、文字列表示と拡張比較について紹介させていただきます。
ダンダーって何?
上記の「Everything is an Object」は例えではなく、実際のPython構造です。Pythonにはobjectというクラスが有り、すべてのクラスはobjectから継承しています。objectクラス内の関数は関数名前後に二つ_をついているのでダンダーと呼ばれています。ダンダー(Dunder)は英語のDouble underscoreの略です。この様な関数は他にSpecial methodsやMagic methodsと呼ばれていますが、全部同じ物を指しています。
ダンダーはPythonの特徴とも言われていますが、個人的にはprint()と似たただのビルトイン関数だと思います。OOPのPythonではクラスの扱いが大事で、dunderを習得すればクラスの扱い方が大きく変わります。
インスタンス生成
def __init__(self):
インスタンスの初期化。クラスからインスタンスを生成した後、実行される関数です。初期化(initialize)の関数なので最初の関数だと理解してる方もいるかと思いますが、実は__init__
はobject内で二番目に実行される関数です。
def __new__(cls):
インスタンスの生成。インスタンス創造時に実行される関数で、object内で一番目に実行される関数です。インスタンス創造時に__new__
の中からスーパークラスの__new__
を戻り値にしてから、__init__
を実行する仕組みになっています。普段は__new__
はあまり使いませんが、使おうとした時は必ずsuper().__new__(cls)
を戻り値に設定しましょう。
文字列表示
def __str__(self):
読みやすい文字列の表示。print()
/str()
/format()
等のビルトイン関数から初めに呼ばれる関数です。クラスに__str__
が存在しなかったら、print()等の関数は__repr__
を呼びます。
def __repr__(self):
明確に定義された文字列の表示。repr()
関数からも呼ばれること以外は基本__str__
と同じです。違いと言えばこの関数が定義された原因は、stdoutで何が起きたかを観察するためでより明確な内容の表示をします。
def __format__(self, format):
格式変更をした文字列の表示。format()
はクラス以外にも引数を一つ必要で、引数に応じた格式変更を行う関数です。デフォルトで引数に何も入れないと__str__
を戻り値にします。
def __bytes__(self):
ビット表示。bytes()
で呼ぶ関数で、一般的にビット化した何かを戻り値にします。
拡張比較(Rich Comparison)
拡張比較はクラスが演算子で他のインスタンスと比較された時の対応を示しています。ここの関数を自分で設定する時、くれぐれも比較する対象が同じクラスかのif判定を加えるのを忘れないように。
def __lt__(self, other):
self < other。
def __le__(self, other):
self ≤other。
def __gt__(self, other):
self > other。
def __ge__(self, other):
self ≥ other。
def __eq__(self, other):
self == other。__hash__
関数を設置するとき必ず設定する関数とも知られてる。
def __ne__(self, other):
self != other
他のダンダー
他にも色んなダンダーがあります。しかしMediumは記事内メニューの機能がなく、同じ記事に書き込むとバカ長くなるので、別々に書き込みます。次回は属性のアクセス関連ダンダーからです。完成次第公開します。
Pythonの公式ドキュメントにも全ダンダー記載されています、興味ある方はどうぞご覧ください。
if you like(this_article):
please(CLAPS)
follow(LSC_PSD)
# Thanks :)