有时我们希望自定义类的实例间可以使用,<,<=,>,>=,==,!=符号进行比较,我们自定义比较的行业,例如,有一个矩形的类,比较两个矩形的实例时,比较的是他们的面积.
1 写一个Rect类,用于比较矩形的的面积
from functools import total_ordering
@total_ordering
class Rect(object):
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
# 打印类的时候调用
def __str__(self):
return '(%s,%s)' % (self.w, self.h)
def __lt__(self, other):
return self.area() < other.area()
def __eq__(self, other):
return self.area() == other.area()
a = Rect(1, 2)
b = Rect(1, 3)
print(a < b)
print(a > b) # 在python内部进行了替换 a < b
如果值写__lt__函数和__eq__函数就会出现不能判断出>=,<=等情况
print(a <= b)
TypeError: ‘<=’ not supported between instances of ‘Rect’ and ‘Rect’
需要加上装饰器 @total_ordering # True
2 再写一个Cirle类,用于比较圆的的面积
import functools
import math
@functools.total_ordering
class Cirle(object):
def __init__(self, r):
self.r = r
def area(self):
return self.r ** 2 * math.pi
def __lt__(self, other):
return self.area() < other.area()
def __eq__(self, other):
return self.area() == other.area()
c1 = Cirle(2)
c2 = Cirle(3)
print(c1 > c2) # False
3 使用抽象基类
from functools import total_ordering
import abc
import math
@total_ordering
class Shape(metaclass=abc.ABCMeta):
@abc.abstractmethod
def area(self):
pass
def __lt__(self, other):
return self.area() < other.area()
def __eq__(self, other):
return self.area() == other.area()
class Cirle(Shape):
def __init__(self, r):
self.r = r
def area(self):
return self.r ** 2 * math.pi
class Rect(Shape):
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
a = Cirle(4)
b = Rect(1, 2)
print(a >= b)