案例:

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

  需求:

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

如何解决这个问题?

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

    单个类比较

#!/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. 微信小程序节点查询方法:wx.createSelectorQuery()的使用场景与注意事项

    小程序由于内置于微信,这使得它有了得天独厚的宣传和使用优势,本着学习的心态,我在官网上看了一遍开发文档,大致得出小程序框架的设计模式与使用注意事项(重点来了,其实开发文档某些方面叙述的并不仔细,甚至存 ...

  2. CSS中水平居中的方法

    居中是我们在css中经常遇到的问题,一般有水平居中.垂直居中.垂直水平居中这3种情况,那么今天首先就来对学习到的水平居中的方法做个总结笔记. css水平居中 text-align:center 它的效 ...

  3. Java编程思想读书笔记(二)【一切都是对象】

    begin 2018年1月9日17:06:47 第二章 一切都是对象 Java语言假设我们只进行面向对象的程序设计. 2.1 用引用操纵对象 每种编程语言都有自己的操纵内存元素的方式 操纵内存元素的方 ...

  4. 移动web开发之touch事件

    前面的话 iOS版Safari为了向开发人员传达一些特殊信息,新增了一些专有事件.因为iOS设备既没有鼠标也没有键盘,所以在为移动Safari开发交互性网页时,常规的鼠标和键盘事件根本不够用.随着An ...

  5. Java中组合 设计技巧 实例

    关于组合 和 集成 先放两篇文章:这两篇文章写的太好了. http://blog.csdn.net/u013905744/article/details/51752044    Java的组合(持有对 ...

  6. Cain工具ARP欺骗攻击

    OS:Win7工具:Cainhttp://pan.baidu.com/s/1xq9lW 密码:409z 网络:本机和被攻击电脑有线连接路由器. Cain是有名的局域网嗅探工具,有丰富的功能.比如可以解 ...

  7. React入门实例教程

    文章转自:阮一峰 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React ...

  8. POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】

    Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9897   Accepted: 41 ...

  9. 二维字符数组利用gets输入

    char a[10][81];for(int i=0;i<10;i++)gets(a[i]); a是二维数组的数组名,相当于一维数组的指针,所以a[i]就相当于指向第i个数组的指针,类型就相当于 ...

  10. GSS4 - Can you answer these queries IV(线段树懒操作)

    GSS4 - Can you answer these queries IV(线段树懒操作) 标签: 线段树 题目链接 Description recursion有一个正整数序列a[n].现在recu ...