環境
- Windows 10
- Python 3.10.1
- VSCode
この記事は何?
- Pythonで作成した独自クラスは、デフォルトでは比較演算ができない
- そのため、オブジェクト同士が同値であることを==等を用いて比較しようとしてもFalseになってしまい、テストの際などにちょっと悲しい
なぜ自分で作成したクラスは比較できないのか
単にコンストラクタや、プロパティ、メソッドを定義しただけでは、足りず、以下のような特殊メソッドを定義する必要があるため
※厳密には、__eq__が定義されていれば、__ne__はその反対なので、定義されていなくてもOK
メソッド名 | 内容 |
---|---|
lt | Less Than:未満 |
le | Less Than or Equal:以下 |
eq | Equal:同じ |
ne | Not Equal:違う |
gt | Greater Than:より大きい |
ge | Greater Than or Equal:以上 |
めんどくさくない?
- 毎回6つもメソッドを定義してられないので、Pythonではfunctoolsパッケージのtotal_orderingというでコレーターが存在しており、こちらを使用することで上記よりも簡潔に比較演算を定義することができます
- functoolsのtotal_orderingというデコレータが、__eq__と__lt__の内容から、その他の比較メソッドを推測してくれるhttps://docs.python.org/ja/3/library/functools.html#functools.total_ordering
- こちらを使用することにより、以下のように、__eq__と__lt__の2つだけでよくなります(ちなみに、以下はwebスクレイピングで取得したWebElementを管理する用の自作クラスです)
shared\Domain\xweb_element.py
from shared.Domain.i_xweb_element import IXWebElement
from selenium.webdriver.remote.webelement import WebElement
from functools import total_ordering
@total_ordering # デコレーター
class XWebElement(IXWebElement):
def __init__(self, element: WebElement, value):
self.element = element
self.value = value
def __eq__(self, other):
if not isinstance(other, XWebElement):
return NotImplemented
return (self.element, self.value) == (other.element, self.value)
def __lt__(self, other):
if not isinstance(other, XWebElement):
return NotImplemented
return (self.element, self.value) < (other.element, self.value)
def get_element(self):
return self.element
def get_value(self):
return self.value
まとめ
いかがでしたでしょうか。本記事では、Pythonで自作クラスの比較演算する方法(同値性比較の実装)紹介しています。ぜひ参考にしてみてください