__lt__ is less than, __le__ is less than or equal to, __gt__ is greater than, __ge__ is greater than or equal to, __eq__ is equal to, __ne__ is not equal to
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) #When r1<r2 is called, r1 actually calls the __lt__(r2) method, and r2 is used as a parameter
Output result:
True
>>>
If you want to implement these methods, you can overload these methods. If you use total_ordering to simplify the process, you can only define less than and equal to, and you can automatically generate other operator overloads.
>>> 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() """ <= > >= != are all judged by less than and equal logic """ r1 = Rectangle(4,3) r2 = Rectangle(4,2) print (r1<r2) #r1.__lt__(r2)
Output result:
False
>>>
If you define other graphics for comparison, other graphics without overloaded operators can only be used as parameters, not as callers. If you define a circle object c1 (without overloaded operators), then r1<c1 will return True or False, an exception will be thrown if c1<r1.
If the operator is overloaded when defining other graphics, it is too troublesome. You can define a common base class sheap for these graphs, and implement overloaded operator functions in the base class. An additional abstract interface area is defined, which can be compared, and all implement this abstract interface 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 can simplify overloaded operators from abc import ABCMeta, abstractmethod #define virtual functions using @total_ordering #decorator class shape(object): @abstractmethod #Decorator def area (self): #Define virtual functions, those who inherit this class must implement 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)