相较于 a.is_equal(b), a.is_greater_than(b) 这种语法的函数调用来进行对象的对比, 使用运算符的比较 a == b, a > b 这样的语法更加直观。
Python 种提供了一系列的魔术方法, 来实现对象的对比。
方法 | 说明 | 运算符 |
__eq__(self, other) | 定义相等运算符的行为 | == |
__ne__(self, other) | 定义不等式运算符的行为 | != |
__lt__(self, other) | 定义小于运算符的行为 | < |
__le__(self, other) | 定义小于或等于运算符的行为 | <= |
__gt__(self, other) | 定义大于运算符的行为 | > |
__ge__(self, other) | 定义大于或等于运算符的行为 | >= |
示例, 未自定义比较方法时, 使用 == 运算符返回 False
In [1]: class Card:
...: def __init__(self, suit, rank):
...: self.suit = suit
...: self.rank = rank
...:
In [2]: hearts8 = Card('Hearts', '8')
...: hearts8b = Card('Hearts', '8')
In [3]: hearts8 == hearts8b
Out[3]: False
自定义比较方法, 当卡牌同样大小时, 按照花色进行比较Clubs (♣) < Diamonds (♦) < Hearts (♥) < Spades (♠)
In [1]: SUITS = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
...: RANKS = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
...:
...: class Card:
...: def __init__(self, suit, rank):
...: self.suit = suit
...: self.rank = rank
...:
...: @property
...: def score(self):
...: return RANKS.index(self.rank)*10 + SUITS.index(self.suit)
...:
...: def __eq__(self, other):
...: return self.score == other.score
...:
...: def __lt__(self, other):
...: return self.score < other.score
...:
In [2]: heartsJ = Card('Hearts', 'J')
...: SpadesJ = Card('Spades', 'J')
In [3]: heartsJ < SpadesJ
Out[3]: True
In [4]: heartsJ > SpadesJ
Out[4]: False
In [5]: heartsJ <= SpadesJ
---------------------------------------------------------------------------
TypeError: '<=' not supported between instances of 'Card' and 'Card'
可以看到, 执行 heartsJ < SpadesJ 时, 调用了 __lt__ 方法, 返回了卡牌的带花色比对结果。
执行 heartsJ > SpadesJ, 没有找到 __gt__ 方法, 降级寻找到 SpadesJ < heartsJ 的比对结果, 还是调用了 __lt__ 方法。
由于未定义 __le__ 方法, 所以执行 heartsJ <= SpadesJ 时, 会返回 TypeError