まとめへのリンク
はじめに
Pythonの勉強をするために、acopyという群知能ライブラリを写経していました。
acopyでは、多くのPythonの面白い文法・イディオムが使われており、その中でも便利だなぁというのをまとめています。
今回は、クラスのインスタンスに比較演算が行えるようにします。
比較演算
Pythonの組み込みデータ型には、比較演算が定義されています。
例えば、もちろんintクラスのインスタンスの数字は当然ソート・比較が可能です。
'''
[-2, -1, 1, 2, 3, 5]
'''
a = [1, 2, 3, 5, -1, -2]
a.sort()
print(a)
以上のように、ソートが行え、当然「<=
」などの演算子も使えます。
独自クラス
しかし、自分で作った独自クラスに関しては比較演算を行えません。
比較演算を行うために必要な特殊属性メソッド
-
__lt__
less than -
__le__
less or equal -
__eq__
equal -
__ne__
not equal -
__gt__
greater than -
__ge__
greater or equal
が定義されていないためです。
そこで、これらの属性を自分で定義することで、クラスのインスタンスを比較・ソートすることができます。
実装してみる
import functools
@functools.total_ordering
class A:
def __init__(self, x):
self.x = x
def __repr__(self):
return f"x = {self.x}"
def __eq__(self, other):
return self.x == other.x
def __lt__(self, other):
return self.x < other.x
'''
[x = 2, x = 3, x = 10, x = 20]
'''
arr = [A(10), A(20), A(3), A(2)]
arr.sort()
print(arr)
class Aには、__repr__
属性が定義されていて、これによって、printを見やすくすることができます。
ここで、__eq__
と__lt__
が定義されており、これによって、他のインスタンスother
との比較関係を表します。
__lt__
のself.x < other.x
は、相手より小さければTrueを返し、これ以上交換しなくて良い!というイメージになっています。
実は、__eq__
と__lt__
しか上のクラスには定義されていませんが、ちゃんと機能してくれます。
これは、functoolsのtotal_orderingというデコレータを使用することで、その他の比較メソッドを推測してくれるためです。
まとめ
クラスに直接比較演算が行えるとソート、そしてもちろんif文などで便利です。
__eq__
, __lt__
のみ定義するだけで比較できるのは便利だなと感じました。
C++非常に面倒なので...