案例:

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

  需求:

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

如何解决这个问题?

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

    单个类比较

#!/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. Linux上leveldb的安装和使用

    1.首先从官网上下载leveldb进行编译 git clone https://github.com/google/leveldb.git cd leveldb make 2.将头文件和动态链接库拷到 ...

  2. 记一次使用Node.js electron打包网站的记录

    具体步骤请参考:http://blog.csdn.net/a727911438/article/details/70834467 打包时出现了不少问题,逐一记录下来以供其他人参考. package.j ...

  3. Twisted使用和scrapy源码剖析

    1.Twisted是用Python实现的基于事件驱动的网络引擎框架. 事件驱动编程是一种编程范式,这里程序的执行流由外部事件来决定.它的特点是包含一个事件循环,当外部事件发生时使用回调机制来触发相应的 ...

  4. java指令重排序的问题

    转载自于:http://my.oschina.net/004/blog/222069?fromerr=ER2mp62C 指令重排序是个比较复杂.觉得有些不可思议的问题,同样是先以例子开头(建议大家跑下 ...

  5. echart(2),模拟数据导入篇

    先上图,就是介样子的: 所模拟的效果就是讲左下角的li里面的数据取出来,然后用环形图的展示出数据. 看代码截图: 1.总的框架图: 2.循环取数据的js代码: 3.echart提供额官方api的代码 ...

  6. C#操作MongoDB的简单实例

    最近比较忙,很久没更新了(虽然没人看,也没人在乎,也要记得be yourself), 前面分享了一些mongodb的安装和简单的语法,今天模仿支付宝首页的模块移动功能,用mongo做一个简单的后台实例 ...

  7. Zabbix实战-简易教程(4)--Server端安装

    在数据库安装完成后,接着开始安装server端了.我们这里采用yum安装. 3.2.0 安装需求 ● PHP 5.6.18 ● curl 7.47.1 ● zabbix_server (Zabbix) ...

  8. ICP在pose-graph中的作用

    从1维的角度进行解释: 1m P0   o-----------------------o   P1 假如LOAM计算的两个车辆初始位姿P0.P1如上图所示,作为pose-graph的两个顶点.那么二 ...

  9. 使用mysql悲观锁解决并发问题

    最近学习了一下数据库的悲观锁和乐观锁,根据自己的理解和网上参考资料总结如下: 悲观锁介绍(百科): 悲观锁,正如其名,它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持 ...

  10. hackerrank Alex对战Fedor

    任意门 为了在漫长得飞行旅途中娱乐,Alex和Fedor发明了如下的一个简单的双人游戏.游戏是: 首先, Alex画一个有权无向图.该图中可能有多重边(多重边的权值可能相同或者不同). 然后,Fedo ...