1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Python中級者への道】独自クラスを比較演算を可能にする

Posted at

まとめへのリンク

はじめに

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++非常に面倒なので...

参考文献

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?