案例:

  有时我们希望自定义的类,实例间可以使用比较运算符进行比较,我们自定义比较的行为。

  需求:

    有一个矩形的类,我们希望比较两个矩形的实例时,比较的是他们的面积

如何解决这个问题?

  在类中重新定义比较运算符,所有的比较运算可以简化为两个基本的比较运算,小于和等于比较

    单个类比较

#!/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_如何让类支持比较运算?的更多相关文章

  1. 让ecshop模板支持php运算

    让ecshop模板支持php运算在 cls_template.php 底部加入函数: /** * 处理if标签 * * @access public * @param string $tag_args ...

  2. 初识Java(Java数字处理类-大数字运算)

    一.大数字运算 在 Java 中提供了大数字的操作类,即 java.math.BigInteger 类与  java.math.BigDecimal 类.这两个类用于高精度计算,体重 BigInteg ...

  3. Android开发调试日志工具类[支持保存到SD卡]

    直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...

  4. 支持异步写入的日志类,支持Framework2.0

    因为工作需要需要在XP上运行一个C#编写的Winform插件,我就用Framework2.0,因为存在接口交互所以想保留交易过程的入参出参. 考虑到插件本身实施的因素,就没有使用Log4.NLog等成 ...

  5. jetty el表达式不支持三元运算

    在jetty跑web程序中不支持三元运算 要换一种格式写 这种代码在jsp页面用jetty跑起来是会报错的,然后调换一下顺序就可以了  或者在后面那个加个括号也可以 

  6. C#写文本日志帮助类(支持多线程)

    代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...

  7. CodePage------Encoding 类支持的编码以及与这些编码关联的代码页(CodePage)

    Encoding 类 .NET Framework 4  表示字符编码. 继承层次结构 System.Object  System.Text.Encoding    System.Text.ASCII ...

  8. 遍历指定包名下所有的类(支持jar)(转)

    支持包名下的子包名遍历,并使用Annotation(内注)来过滤一些不必要的内部类,提高命中精度. 通过Thread.currentThread().getContextClassLoader()获取 ...

  9. Java String类的比较运算

    面试题:(多选)以下返回true的有() A. "beijing" == "beijing" B. "beijing".equals(new ...

随机推荐

  1. Mysql查询不为null值

    Mysql本以为查询不为null就是!=null可是结果查询出来什么都没有,后来才发现不为null应该是is not null ,为null应该是is null.

  2. 利用jquery encoder解决XSS脚本注入所产生的问题

    问题现象:前端接收到后台一个数据(其中包含html)标签,自动转译成html页面元素,且自动执行了脚本,造成了前端页面的阻塞 接受的后台数据为大量重复的如下代码 ");</script ...

  3. vue 设计日历表

    日历的功能,我们会经常用到,且逻辑比较复杂,小算法较多,花了半天时间写了个,特此详记. 先贴图 功能阐述:返回本月不多说,设置工作日和节假日是为了公司制度需要,后台会有假日表来记录. 为了适应于vue ...

  4. spring 实现邮箱发送

    使用spring mail 实现的邮箱发送功能,包括附件的发送(附件发送要保证附件存在的路径是真实),使用maven集成jar包,通过spring mvc 实现前后台的调用,发送方使用的是163邮箱, ...

  5. 记录一下自己爬虎牙LOL主播的爬虫思路

    1.明确爬虫目的 爬虫目的需要我们明确的,没有目的的爬虫都是耍流氓!像我这次爬虫目的能不能从网页上爬下来. 2.怎么来爬? a. 先要找到具有唯一性的标签 <li class="gam ...

  6. AttributeError: 'int' object has no attribute 'log'

    我们有时候在对组数进行操作时候,偶尔会出现这个问题. 比如: #coding:utf- import pandas as pd import numpy as np if __name__ == '_ ...

  7. hackerrank Ticket

    传送门 题意:n个人排队买票,要把他们拆成k条队到k个窗口买,可以有队伍为空,每条队的顺序保持拆之前的顺序.如果某人和他前一个人买的票相同,就可以打八折,求最小花费. 题解:拆成k条队意味着只有[n- ...

  8. 【Java学习笔记之五】java数组详解

    数组 概念 同一种类型数据的集合.其实数组就是一个容器. 数组的好处 可以自动给数组中的元素从0开始编号,方便操作这些元素. 格式1: 元素类型[] 数组名 = new 元素类型[元素个数或数组长度] ...

  9. Linux 文件操作命令-Linux基础环境命令学习笔记

    1.文件目录操作 1)路径识别 a.绝对路径,以根目录开始 b.相对路径,以当前目录开始,不需从根目录开始写起 2)命令 man ls 查看ls命令帮助 cd /var/log 切换进入log目录(. ...

  10. linux 内核提权

    不经意间找到了大牛总结的一些Linux提权exp 我直接借花献佛分享给大家 #CVE #Description #Kernels CVE-2017-1000367 [Sudo] (Sudo 1.8.6 ...