1. 程式人生 > >python_如何讓類支持比較運算?

python_如何讓類支持比較運算?

進行 重復 width 比較 bstr str 實現 spa 單個

案例:

  有時我們希望自定義的類,實例間可以使用比較運算符進行比較,我們自定義比較的行為。

  需求:

    有一個矩形的類,我們希望比較兩個矩形的實例時,比較的是他們的面積

如何解決這個問題?

  在類中重新定義比較運算符,所有的比較運算可以簡化為兩個基本的比較運算,小於和等於比較

    單個類比較

#!/usr/bin/python3

from math import pi


class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    def get_area(self):
        return round(pow(self.radius, 2) * pi, 2)

    # 重定義小於比較
    def __lt__(self, other):
        return self.get_area() < other.get_area()

    # 重定義等於比較
    def __eq__(self, other):
        return self.get_area() == other.get_area()

if __name__ == ‘__main__‘:
    c1 = Circle(3.0)
    c2 = Circle(5.0)

    print(c1 < c2)      # c1.__le__(c2)
    print(c1 == c2)     # c1.__eq__(c2)

  

    兩個類比較

#!/usr/bin/python3

from math import pi


class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    def get_area(self):
        return round(pow(self.radius, 2) * pi, 2)

    # 重定義小於比較
    def __lt__(self, other):
        return self.get_area() < other.get_area()

    # 重定義等於比較
    def __eq__(self, other):
        return self.get_area() == other.get_area()

if __name__ == ‘__main__‘:
    c1 = Circle(3.0)
    c2 = Circle(5.0)

    print(c1 < c2)      # c1.__le__(c2)
    print(c1 == c2)     # c1.__eq__(c2)


# !/usr/bin/python3

from math import pi


class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    def get_area(self):
        return round(pow(self.radius, 2) * pi, 2)

    # 重定義小於比較
    def __lt__(self, other):
        return self.get_area() < other.get_area()

    # 重定義等於比較
    def __eq__(self, other):
        return self.get_area() == other.get_area()


class Rectangle(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def get_area(self):
        return self.width * self.height

    # 重定義小於比較
    def __lt__(self, other):
        return self.get_area() < other.get_area()

    # 重定義等於比較
    def __eq__(self, other):
        return self.get_area() == other.get_area()


if __name__ == ‘__main__‘:
    c1 = Circle(5.0)
    R1 = Rectangle(4.0, 5.0)

    print(c1 > R1)  # c1.__le__(c2)
    print(c1 == R1)  # c1.__eq__(c2)

  

  會出現一個問題,重復代碼,如何解決?

    通過functools下類的裝飾器total_ordering進行比較

# !/usr/bin/python3

from math import pi
from abc import abstractmethod
from functools import total_ordering


@total_ordering
class Shape(object):
    """
    定義一個抽象類,重定義比較運算,再定義抽象方法,然後子類通過這個方法進行比較,
    其他子類比較類都需要重構抽象方法,實現比較運算
    """
    
    # 標記比較方法,抽象方法
    @abstractmethod
    def get_area(self):
        pass
    
    # 重定義小於比較
    def __lt__(self, other):
        return self.get_area() < other.get_area()
    
    # 重定義等於比較
    def __eq__(self, other):
        return self.get_area() == other.get_area()


class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def get_area(self):
        return round(pow(self.radius, 2) * pi, 2)
    

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def get_area(self):
        return self.width * self.height


if __name__ == ‘__main__‘:
    c1 = Circle(5.0)
    R1 = Rectangle(4.0, 5.0)
    
    print(c1 > R1)  # c1.__le__(c2)
    print(c1 == R1)  # c1.__eq__(c2)

  

  

python_如何讓類支持比較運算?