python基础(如何让类支持比较操作)

案例:

有时我们希望自定义的类,实例间可以使用<,<=,>,>=,==,!=符号进行比较,我们自定义比较的行为。例如:有一个矩形的类,我们希望比较两个矩形的实例时,比较的是他们的面积。

比较符号运算符重载,需要实现以下方法:

__lt__,__le__,__gt__,__ge__,__eq__,__ne__

使用标准库下的functools下的类装饰器total_ordering可以简化此过程,此装饰器是在python2.7的时候加上的,它是针对某个类中如果定义了__lt__、__le__、__gt__、__ge__这些方法中的至少一个,使用该装饰器,则会自动的把其他几个比较函数也实现在该类中

 

from math import pi
from functools import total_ordering
from abc import abstractmethod     #调用抽象基类方法,让继承父类的子类实现父类的方法

@total_ordering     #定义语法糖装饰器
class Shape(object):
    @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):   #定义相等方法
        print('in__eq__')
        if not isinstance(obj,Shape):
            raise TypeError('obj is not Shape')
        return self.area() == obj.area()

class Rectangle(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,radius):
        self.radius = radius

    def area(self):
        return self.radius * 2 * pi

class Square(Shape):   #计算正方形面积
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side * self.side

r1 = Rectangle(5,3)
s1 = Square(4)
c1 = Circle(3)

print(c1 <= r1)  #r1.__lt__(r2)
print(c1 >= s1)  #r1.__lt__(r2)
print(r1 == s1)  #r1.__lt__(r2)
print(r1 != 1)   #报错

你可能感兴趣的:(python高级(一))