需求:
有时我们希望自定义类,实例间可以使用<,<=,>,>=,==,!=,符号进行比较,我们自定义比较的行为,例如,有一个矩形的类,我们希望比较两个矩形的实例时,比较的是他们的面积。
class Rectangel:
def __init__(self,w,h):
self.w = W
self.h = h
def area(self):
return sefl.w * self.h
rect1 = Rectangel(5,3)
rect2 = Rectangel(4.4)
rect1 > rect2 # => rect1.area() > rect2.area()
思路
1、比较符号运算符重载,需要实现以下方法
__lt__,__le__,__gt__,__ge__,__eq__,__ne_
2、使用标准库下的functools下类装饰器total_ordering可以简化此过程
代码:
方法1:
class Rectangel:
def __init__(self,w,h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
def __lt__(self,obj):
print(‘in__lt__‘)
return self.area() < obj.area()
def __le__(self,obj):
print(‘in__le__‘)
return self.area() <= obj.area()
rect1 = Rectangel(5,3)
rect2 = Rectangel(4,4)
#rect1 > rect2 # => rect1.area() > rect2.area()
print(rect1 < rect2) # rect1.__lt__(rect2)
print(rect1 <= rect2)
方法二:
from functools import total_ordering
@total_ordering
class Rectangel:
def __init__(self,w,h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
def __lt__(self,obj):
print(‘in__lt__‘)
return self.area() < obj.area()
def __eq__(self,obj):
print(‘in__eq__‘)
return self.area() == obj.area()
class Circle(object):
def __init__(self,r):
self.r = r
def area(self):
return self.r ** 2 * 3.14
rect1 = Rectangel(5,3)
rect2 = Rectangel(4,4)
c1 = Circle(3)
#rect1 > rect2 # => rect1.area() > rect2.area()
print(rect1 < c1)
print(c1 > 1)
print(rect1 < rect2) # rect1.__lt__(rect2)
print(rect1 >= rect2)
方法三:
from functools import total_ordering
from abc import ABCMeta, abstractmethod
@total_ordering
class Shape(object): # 把运算符重载的函数都放到公共的抽象基类中,这样可以避免其他的类都要写运算符的函数,其他的函数中只要实现area()的方法就可以了
# 再定义一个抽象的接口,能比较的都要实现这个area,否则不能进行比较
@abstractmethod
def area(self): # 描述一下抽象的接口,它的子类都要实现这个接口
pass
def __lt__(self,obj):
print(‘in__lt__‘)
if not isinstance(obj,Shape):
raise TypeError(‘obj is not Shape‘)
return self.area() < obj.area()
def __eq__(self,obj):
if not isinstance(obj,Shape):
raise TypeError(‘obj is not Shape‘)
print(‘in__eq__‘)
return self.area() == obj.area()
class Rectangel(Shape):
def __init__(self,w,h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
class Circle(Shape):
def __init__(self,r):
self.r = r
def area(self):
return self.r ** 2 * 3.14
rect1 = Rectangel(5,3)
rect2 = Rectangel(4,4)
c1 = Circle(3)
#rect1 > rect2 # => rect1.area() > rect2.area()
print(rect1 < c1)
print(c1 > rect2)
print(rect1 < rect2) # rect1.__lt__(rect2)
print(rect1 >= rect2)
原文:https://www.cnblogs.com/Richardo-M-Q/p/13363736.html