7-5 如何让类支持比较操作
Posted 石中玉smulngy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7-5 如何让类支持比较操作相关的知识,希望对你有一定的参考价值。
__lt__小于、__le__小于等于、__gt__大于、__ge__大于等于、__eq__等于、__ne__不等于
class Rectangle(object): def __init__(self,w,h): self.w = w self.h = h def area(self): return self.w * self.h def __lt__(self,obj): print(\'in __lt__\') return self.area()<obj.area r1 = Rectangle(2.2,3.2) r2 = Rectangle(2.1,3.3) print (r1<r2) #r1.__lt__(r2) #调用r1<r2时实际上是r1调用__lt__(r2)方法,r2做为参数
输出结果:
True
>>>
如果要实现这些可以运算符重载这些方法,如果使用total_ordering可以简化过程,只定义小于和等于,就可以,能自动生成其他的运算符重载
>>> help(total_ordering) Help on function total_ordering in module functools: total_ordering(cls) Class decorator that fills in missing ordering methods
from functools import total_ordering @total_ordering class Rectangle(object): def __init__(self,w,h): self.w = w self.h = h def area(self): return self.w * self.h def __lt__(self,obj): print(\'in __lt__\') return self.area()<obj.area() def __ge__(self,obj): print(\'in __ge__\') return self.area() == obj.area() """ <= > >= != 都是通过小于和等于逻辑判断出 """ r1 = Rectangle(4,3) r2 = Rectangle(4,2) print (r1<r2) #r1.__lt__(r2)
输出结果:
False
>>>
如果再定义其他图形做比较,其他图形如没重载运算符,只能做为参数,不能做为调用者,若定义 一个圆对象c1(没重载运算符),那么r1<c1会返回True或False,若c1<r1则会抛出一个异常。
如若定义 其他图形时都重载运算符又太麻烦。可以会这些图形定义一个公共基类sheap,在基类里实现重载运算符函数。额外定义一个抽象的接口area,能比较的,都实现这个抽象接口area
>>> from abc import ABCMeta >>> from abc import abstractmethod
>>> help(abstractmethod) Help on function abstractmethod in module abc: abstractmethod(funcobj) A decorator indicating abstract methods. Requires that the metaclass is ABCMeta or derived from it. A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods are overridden. The abstract methods can be called using any of the normal \'super\' call mechanisms. Usage: class C: __metaclass__ = ABCMeta @abstractmethod def my_abstract_method(self, ...): ...
from functools import total_ordering #total_ordering 可以简化重载运算符 from abc import ABCMeta,abstractmethod #定义虚函数使用 @total_ordering #装饰器 class shape(object): @abstractmethod #装饰器 def area(self): #定义虚函数,继承此类的必须实现 pass def __lt__(self,obj): print(\'in __lt__\') if not isinstance(obj,shape): #判断obj是不是shape类型不是抛出异常 raise TypeError(\'obj is not shape\') return self.area()<obj.area() def __ge__(self,obj): print(\'in __ge__\') if not isinstance(obj,shape): raise TypeError(\'obj is not shape\') return self.area() == obj.area() class Rectangle(shape): def __init__(self,w,h): self.w = w self.h = h def area(self): return self.w * self.h class Circle(shape): def __init__(self,r): self.r = r def area(self): return self.r ** 2 * 3.14 r1 = Rectangle(4,3) c1 = Circle(2) print (c1<r1) #r1.__lt__(r2)
以上是关于7-5 如何让类支持比较操作的主要内容,如果未能解决你的问题,请参考以下文章