Python. Overloading binary arithmetic operators in classes

Overloading binary arithmetic operators in classes


Search other resources:

Contents


1. General information about overloading binary arithmetic operators +, , *, /, //, %

Binary arithmetic operators in classes take 2 operands. The general form of calling a binary arithmetic operator is:

res = a op b

where

  • a, b – operands on which the operation is performed;
  • op – one of the operations +, –, *, /, //, %;
  • res – the resulting object.

To overload the corresponding binary operator in a class, you must implement the corresponding method.

Below is a list of common methods for overloading binary operators +, -, *, /, //, %, operating on objects:

  • __add__() – overload of the binary operator + (addition). The method is called in an expression like a+b;
  • __sub__() – binary operator overloading (subtraction). The method is called when objects a-b are subtracted;
  • __mul__() – binary operator overload * (multiplication). The method is called when the two operands a*b are multiplied;
  • __div__() – overload of the binary operator / (division). Called in expressions like a/b;
  • __mod__() – overload of binary operator % (remainder from division). Called in expression a%b;
  • __floordiv__() – binary operator overload // (divide with rounding down). Called in the expression a//b.

 

2. An example of overloading the +, – operators. Class Point

The example declares the Point class, which implements a point on the coordinate plane. The class overloads the + (addition) and (subtraction) operators. To do this, the __add__() and __sub__() methods are declared in the class.

# Overloading the binary operator +

# A class that describes a point on a coordinate plane
class Point:

    # Class constructor
    def __init__(self, x, y):
        self.x = x
        self.y = y
        return

    # Methods for accessing the fields self.x, self.y
    def GetX(): return self.x
    def GetY(): return self.y
    def SetXY(self, x, y):
        self.x = x
        self.y = y
        return

    #-------------- Operator overloading methods --------------
    # Binary operator overload + (object summation) - __add__() method
    def __add__(self, pt):
        obj = Point(self.x + pt.x, self.y + pt.y)
        return obj

    # Binary subtraction operator overload - __sub__() method
    def __sub__(self, pt):
        # coordinate subtraction
        obj = Point(self.x - pt.x, self.y - pt.y)
        return obj

    # ---------------------------------------------------------
    # Method that prints the values of internal x, y coordinates
    def Print(self, msg):
        print(msg, " => x = ", self.x, "; y = ", self.y)
        return

# Testing
pt1 = Point(1,3)
pt1.Print("pt1")

pt2 = Point(2,6)
pt2.Print("pt2")

pt3 = pt1 + pt2
pt3.Print("pt1 + pt2")

(pt1-pt2).Print("pt1 - pt2")

Result

pt1 => x = 1, y = 3
pt2 => x = 2, y = 6
pt1 + pt2 => x = 3, y = 9
pt1 - pt2 => x = -1, y = -3

 

3. An example of operator overloading +, , *, /, //, % for the Fraction class

The example declares the class Fraction in which the standard binary arithmetic operators are overloaded.

For operators +, , *, /, the corresponding operations of addition, subtraction, multiplication, division of two fractions are performed. The // (integer division) operator returns a fractional number from the division of the operands. The % (remainder) operator returns an integer from the division of the operands.

The class contains the Normal() method, which normalizes the fraction

-8/-12 = 2/3

The text of the program is as follows

# Overloading the binary operator +

# The class that describes the fraction
class Fraction:

    # Class constructor, num - numerator, denom - denominator
    def __init__(self, num, denom):
        self.num = num
        self.denom = denom

        # Correction num, denom
        if self.num == 0: self.num = 1
        if self.denom == 0: self.denom = 1

        self.Normal()
        return

    # Methods for accessing the fields self.num, self.denom
    def GetNum(): return self.num
    def GetDenom(): return self.denom
    def Set(self, num, denom):
        self.num = num
        self.denom = denom
        return

    #-------------- Operators overloading methods --------------
    # Overloading of the binary operator + (fraction summation) - the __add__() method
    def __add__(self, frac):
        obj = Fraction((self.num*frac.denom+self.denom*frac.num), self.denom*frac.denom)
        return obj

    # Overloading the binary subtraction operator - __sub__() method
    def __sub__(self, frac):
        # subtract fractions
        obj = Fraction((self.num*frac.denom-self.denom*frac.num), self.denom*frac.denom)
        return obj

    # Overloading binary * (multiply) - __mul__() method
    def __mul__(self, frac):
        obj = Fraction(self.num*frac.num, self.denom*frac.denom)
        return obj

    # Overloading binary / (division) - метод __div__()
    def __div__(self, frac):
        obj = Fraction(self.num*frac.denom, self.denom*frac.num)
        return obj

    # Overloading binary // (integer division) - метод __floordiv__()
    def __floordiv__(self, frac):
        # The method returns the result of division of type float
        return float((self.num*frac.denom) / (self.denom*frac.num))

    # Overloading the binary operator % (taking the remainder) - the __mod__() method
    def __mod__(self, frac):
        # The method returns the result of division of type int
        return int((self.num*frac.denom) / (self.denom*frac.num))

    # ---------------------------------------------------------
    # Method that outputs the value of internal x, y coordinates
    def Print(self, msg):
        print(msg, " => ", self.num, " / ", self.denom)
        return

    # Method that normalizes the fraction 8/12 => 2/3
    def Normal(self):
        t = abs(self.num)
        i = 1
        num = i
        while i <= t:
            if ((self.num%i) == 0) and ((self.denom%i) == 0):
                num = i
            i = i+1

        self.num = self.num / num
        self.denom = self.denom / num

        # (-num)/(-denom) => num/denom
        if (self.num<0) and (self.denom<0):
            self.num = -self.num
            self.denom = -self.denom
        return

# Testing
f1 = Fraction(6, -12)
f1.Print("f1")
f2 = Fraction(2, -12)
f2.Print("f2")

f3 = f1 + f2
f3.Print("f1 + f2")

f3 = f1 - f2
f3.Print("f1 - f2")

f3 = f1 * f2
f3.Print("f1 * f2")

f3 = f1 / f2
f3.Print("f1 / f2")

res = f1 // f2
print("f1 // f2 => ", res) # res = 3.0

res = f1 % f2
print("f1 % f2 => ", res) # res = 3

Result

f1 => 1 / -2
f2 => 1 / -6)
f1 + f2 => -2 / 3
f1 - f2 => -1 / 3
f1 * f2 => 1 / 12
f1 / f2 => 3 / 1)
f1 // f2 => 3.0
f1 % f2 => 3

 


Related topics