python_如何让类支持比较运算?
案例:
有时我们希望自定义的类,实例间可以使用比较运算符进行比较,我们自定义比较的行为。
需求:
有一个矩形的类,我们希望比较两个矩形的实例时,比较的是他们的面积
如何解决这个问题?
在类中重新定义比较运算符,所有的比较运算可以简化为两个基本的比较运算,小于和等于比较
单个类比较
#!/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_如何让类支持比较运算?的更多相关文章
- 让ecshop模板支持php运算
让ecshop模板支持php运算在 cls_template.php 底部加入函数: /** * 处理if标签 * * @access public * @param string $tag_args ...
- 初识Java(Java数字处理类-大数字运算)
一.大数字运算 在 Java 中提供了大数字的操作类,即 java.math.BigInteger 类与 java.math.BigDecimal 类.这两个类用于高精度计算,体重 BigInteg ...
- Android开发调试日志工具类[支持保存到SD卡]
直接上代码: package com.example.callstatus; import java.io.File; import java.io.FileWriter; import java.i ...
- 支持异步写入的日志类,支持Framework2.0
因为工作需要需要在XP上运行一个C#编写的Winform插件,我就用Framework2.0,因为存在接口交互所以想保留交易过程的入参出参. 考虑到插件本身实施的因素,就没有使用Log4.NLog等成 ...
- jetty el表达式不支持三元运算
在jetty跑web程序中不支持三元运算 要换一种格式写 这种代码在jsp页面用jetty跑起来是会报错的,然后调换一下顺序就可以了 或者在后面那个加个括号也可以
- C#写文本日志帮助类(支持多线程)
代码: using System; using System.Configuration; using System.IO; using System.Threading.Tasks; namespa ...
- CodePage------Encoding 类支持的编码以及与这些编码关联的代码页(CodePage)
Encoding 类 .NET Framework 4 表示字符编码. 继承层次结构 System.Object System.Text.Encoding System.Text.ASCII ...
- 遍历指定包名下所有的类(支持jar)(转)
支持包名下的子包名遍历,并使用Annotation(内注)来过滤一些不必要的内部类,提高命中精度. 通过Thread.currentThread().getContextClassLoader()获取 ...
- Java String类的比较运算
面试题:(多选)以下返回true的有() A. "beijing" == "beijing" B. "beijing".equals(new ...
随机推荐
- 【次小生成树】bzoj1977 [BeiJing2010组队]次小生成树 Tree
Description 小 C 最近学了很多最小生成树的算法,Prim 算法.Kurskal 算法.消圈算法等等. 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了.小 P 说,让小 C 求出一 ...
- 《JAVA程序设计与实例》记录与归纳--类与对象
类与对象 概念贴士: 1. 类必须先定义了才能使用.类是创建对象的模板,创建对象也叫类的实例化. 2. 在Java中,使用new关键字来创建对象,一般有一下3个步骤: 1)声 明:声明一个对象,包 ...
- Webpack+vue2.0如何注册全局组件 (01)
Part 1, 问题: webpack + vue2.0框架中,如何在入口js中注册组件? 就是在一个月以前,匆匆闯入vuejs这个社群,基本了解了vuejs的一些基础特性和语法.笔者兴致勃勃地开始想 ...
- Kubernetes 架构(下)- 每天5分钟玩转 Docker 容器技术(121)
上一节我们讨论了 Kubernetes 架构 Master 上运行的服务,本节讨论 Node 节点. Node 是 Pod 运行的地方,Kubernetes 支持 Docker.rkt 等容器 Run ...
- 《SpringMVC从入门到放肆》三、DispatcherServlet的url-pattern配置详解
上一篇我们详细解释了一下SrpingMVC的执行流程以及一些默认的配置,在Spring的思想中,就是默认大于配置.今天我们来详细的研究一下DispatcherServlet的url-pattern配置 ...
- ssm maven spring AOP读写分离
ssm maven spring AOP读写分离 总体流程 配置最开始写在pom.xml文件,解析到数据库配置文件,再解析到spring配置文件. 自定义注解DataSource:通过这个注解并且在s ...
- 2017 CCPC 哈尔滨站 HDU 6242
Geometry Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Other ...
- ACM讲座心得
- 浅析Entity Framework Core2.0的日志记录与动态查询条件
前言 Entity Framework Core 2.0更新也已经有一段时间了,园子里也有不少的文章.. 本文主要是浅析一下Entity Framework Core2.0的日志记录与动态查询条件 去 ...
- jquery的done和then区别
jquery的deferred对象的done方法和then方法都能实现链式调用,但是他们的作用是有区别的,then方法中如果你传递的方法有返回值,那么他会传递给下一个链式调用的方法.而done方法与此 ...