程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python implementation enables classes to support comparison operations

編輯:Python

1、 How to make classes support comparison operations ?

         Actual case :

                 Sometimes we want custom classes , Between instances, you can use ,>=,==,!= Compare symbols , We customize the behavior of comparison . for example , There is a rectangular class , When we want to compare instances of two rectangles , Compare their area .

 class Rectangle:
def __init__(self, w, h):
self.w =w
self.h = h
def area(self):
return self.w*self.h
rect1 = Rectangle(5, 3)
rect2 = Rectangle(4, 4)
# rect1.area() > rect2.area()
rect1 > rect2

         Solution :

                 Comparison symbol operator overloading , The following methods need to be implemented : Less than __lt__, Less than or equal to __le__, Greater than __gt__,_ Greater than or equal to _ge__, be equal to ___eq__, Cannot be on __ne__.

                 Using the standard library funtools Class decorator under total_ordering It can simplify the process of writing all operator overloads .

2、 Code demonstration

(1) Realize the comparison between two instances

from functools import total_ordering
@total_ordering
class Rectangle:
# Define rectangle class
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
# Overload of less than operator ,other For the right object
def __lt__(self, obj):
print('in __lt__')
return self.area() < obj.area()
def __eq__(self, obj): # be equal to
print('in __eq__')
return self.area() == obj.area()
# def __le__(self, obj): # Less than or equal to , The decorator will be created by default
# return self < obj or self == obj
#
# def __gt__(self, obj): # Greater than , The decorator will be created by default
# return not (self < obj or self == obj)
r1 = Rectangle(5, 3)
r2 = Rectangle(4, 4)
# When the interpreter sees such a statement , It's actually calling theta r1.__lt__(r2)
# 3*5=15 Less than 4*4=16
print(r1 < r2)
# Less than or equal to
print(r1 <= r2)
# Add... For filling total_ordering Decorator , You can overload definitions that are equal to and less than
# Two methods can use less than or equal to , The runtime actually invokes only behaviors less than ,
# This is because the decorator is used by default '__lt__ or __eq__ ' Create... For us __le__.
print(r1 <= r2)
print(r1 > r2)
print(r1 >= r2)
print(r1 != r2)
'''
Comparing two instances is not always the same object , For example, define another Circle class ,
Compare the area of circle and rectangle through two instance objects .
'''
class Circle(object):
# Define a circle
def __init__(self, r):
self.r = r
def area(self):
return self.r ** 2 * 3.14
r1 = Rectangle(5, 3)
c1 = Circle(3)
# Compare rectangular and circular areas ,r1 <= c1 Is to support the , If I go the other way c1 <= r1 Also want to support ,
# It needs to be in Circle Class to do the same comparison operator method overloading .
print(r1 <= c1)
print('---')
print(c1 <= r1)

(2) Use abstract interfaces and public base classes to upgrade and optimize the comparison of different instance objects

'''
Write an overload of the comparison operator method for each graph , This way is very troublesome .
We can define a common abstract base class for graphics shape, And in shape Functions that implement these operator overloads in .
In addition, define an abstract interface area All that can be compared should achieve this area,
Let all graphics inherit this common base class , This way is better .
'''
# _*_ encoding:utf-8 _*_
from functools import total_ordering
# Import definition abstract base class library
from abc import ABCMeta, abstractmethod
@total_ordering
class Shape(object):
# Abstract base class of graphics
@abstractmethod # Abstract interface decorator
def area(self):
# Subclasses must implement this interface
pass
# Overload of less than operator ,obj For the right object
def __lt__(self, obj):
# Make type judgment before comparison , You can't compare objects with numbers
if not isinstance(obj, Shape):
raise TypeError('obj is not Shape')
print('in __lt__')
return self.area() < obj.area()
def __eq__(self, obj): # be equal to
if not isinstance(obj, Shape):
raise TypeError('obj is not Shape')
print('in __eq__')
return self.area() == obj.area()
class Rectangle(Shape): # Inherit shape
# Define rectangle class
def __init__(self, w, h):
self.w = w
self.h = h
def area(self):
return self.w * self.h
class Circle(Shape): # Inherit shape
# Define a circle
def __init__(self, r):
self.r = r
def area(self):
return self.r ** 2 * 3.14
'''
Comparing two instances is not always the same object , For example, define another Circle class ,
Compare the area of circle and rectangle through two instance objects .
'''
r1 = Rectangle(5, 3)
c1 = Circle(3)
print(r1 <= c1)
print(r1 > c1)
# Exception verification
# print(r1 > 1)


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved