类比较
数值可以直接进行比较,而集合比较的是包含关系 这两者都可以直接比较,但是对于类来说却不可以直接比较。
a = 2
b = 1
# print(a >1)
# print(a.__gt__(b)) # gt --- >
# 集合比较的是 包含关系
# print({1,2,3} > {4}) # False
# print({1,2,3} > {1,2}) # True
定义两个类,首先在第一个类中,可以相互比较,但是需要定义比较的方法,类之间也是如此,定义比较的方法。但是每比较一次不同的的方式,就要定义一个方法,会造成代码的冗余。
所以可以导入functools这个方法,使用装饰器调用不同的比较方法。
rom 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 f"({self.w},{self.h})"
def __gt__(self, other):
return self.area() > other.area()
# r1 = Rect(1,2)
# r2 = Rect(3,4)
#
# print(r1) # (1,2)
# print(r2)
# 定义一个方法 使其两个可以进行比较 gt方法
# print(r1 > r2)
import math
class Circle(object):
def __init__(self, r):
self.r = r
def area(self):
return self.r**2*math.pi
c = Circle(2)
r = Rect(2,2)
print(c == r)
也可以使用一个类来将比较方法整个在一起,用其子类继承调用方法,相同部分的代码可以节省掉。@total_ordering装饰器就只需要完成__lt__与__gt__两个方法,就可以全部实现。
""""
将共同代码抽出 强制子类 实现area方法
"""
import abc
from functools import total_ordering
import math
@total_ordering
class shape(metaclass=abc.ABCMeta):
@abc.abstractmethod
def area(self):
pass
def __gt__(self, other):
return self.area() > other.area()
def __ge__(self, other):
return self.area() >= other.area()
class Rect(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*math.pi
c = Circle(3)
r = Rect(1,2)
print(c == r )