Python. Overloading the shortened assignment operators

Overloading the shortened assignment operators

Before studying this topic, it is recommended that you familiarize yourself with the following topic:


Search other resources:

Contents


1. Features of overloading shortened assignment operators +=, –+, *=, /=, %=, //=

To overload the shortened assignment operators in a class, you need to declare the following methods:

  • __iadd__() – overloads the shortened assignment operator +=;
  • __isub__() – overloads the operator -=;
  • __imul__() – overloads the operator *=;
  • __idiv__() – overloads the operator /=;
  • __ifloordiv__() – overloads //= operator;
  • __imod__() – overloads %= operator.

Implementing each of these methods in a class requires receiving two parameters:

  • parameter of type self – the current class object (this);
  • a parameter that has the type of the given class. This parameter is the object used on the right side of the shortened assignment statement.

After a class implements methods that overload one of the shorthand assignment operators, the following actions can be performed on objects of this class

obj1 op obj2

where

  • obj1, obj2 – class objects;
  • op – one of the operations +=, -=, *=, /=, //=, %=.

For example, to overload the += operator in class A, there might be something like the following code

class A:

    # ...

    # overloading the += operator
    def __iadd__(self, obj):
        # Actions to be performed
        # ...

# Calling the overloaded operator +=
obj1 = A()
obj2 = A()
obj1 += obj2

 

2. Overloading shortened assignment operators. Class Fraction

The example declares a class Fraction. The class declares two internal variables:

  • num (self.num) – the numerator of a fraction;
  • denom (self.denom) – the denominator of a fraction.

The Fraction class demonstrates +=, -=, *=, /=, %=, //= operators overloading.

# Overloading the +=, -=, *=, /=, %=, //= operators

# A class that describes a fraction given by the numerator and denominator:
# - num - numerator;
# - denom - denominator.
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

    #-------------- Operators overloading methods --------------
    # Overloading the += operator
    # Adding another fraction to a given fraction is the __iadd__() method
    def __iadd__(self, frac):
        obj = Fraction((self.num*frac.denom+self.denom*frac.num), self.denom*frac.denom)
        return obj

    # Overloading the -= operator
    # Subtraction of another fraction from a given fraction is the __isub__() method
    def __isub__(self, frac):
        # subtract fractions
        obj = Fraction((self.num*frac.denom-self.denom*frac.num), self.denom*frac.denom)
        return obj

    # Overloading the *= operator - the __imul__() method
    def __imul__(self, frac):
        obj = Fraction(self.num*frac.num, self.denom*frac.denom)
        return obj

    # Overloading the /= operator - the __idiv__() method
    def __idiv__(self, frac):
        obj = Fraction(self.num*frac.denom, self.denom*frac.num)
        return obj

    # Overloading the //= - the __ifloordiv__() method
    def __ifloordiv__(self, frac):
        # The method returns the result of dividing fractions in the same way as the idiv() method
        return Fraction(self.num*frac.denom, self.denom*frac.num)

    # Overloading the %= operator - the __imod__() method
    def __imod__(self, frac):
        # The method returns the inverted fraction: 5/6 => 6/5
        return Fraction(self.denom, self.num)

    # ---------------------------------------------------------
    # Method that outputs the value of internal coordinates x, y
    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(1, 2) # constructor
f1.Print("f1")

f2 = Fraction(2, 3) # constructor
f2.Print("f2")

f1 += f2 # метод __iadd__()
f1.Print("f1+=f2")

f1 -= f2 # метод __isub__()
f1.Print("f1-=f2")

f1 *= f2 # метод __imul__()
f1.Print("f1*=f2")

f1 /= f2 # метод __idiv__()
f1.Print("f1/=f2")

f1 //=f2 # метод __ifloordiv__()
f1.Print("f1//f2")

f1 %= f1 # метод __imod__()
f1.Print("f1%=f1")

Result

f1 => 1 / 2)
f2 => 2 / 3)
f1+=f2 => 7 / 6
f1-=f2 => 1 / 2)
f1*=f2 => 1 / 3)
f1/=f2 => 1 / 2)
f1//f2 => 3 / 4)
f1%=f1 => 4 / 3)

 

3. An example of overloading shorthand assignment operators. The Point and ArrayPoint classes. Operating with array of points

This example declares the Point and ArrayPoint classes. The Point class describes a point on the coordinate plane. The ArrayPoint class describes an array of points. The array is implemented as a list.

In the ArrayPoint class, the shortened assignment operator += is overloaded, which implements the concatenation of arrays of the ArrayPoint type.

# Overloading the += operator to add lists of objects

# Class describing a point on the coordinate plane (x; y)
class Point:
    # Constructor
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # Methods that return the coordinates of a point
    def GetX(self): return self.x
    def GetY(self): return self.y

    # A method that outputs the coordinates of a point
    def Print(self, msg):
        print(msg, "=> (", self.x, "; ", self.y, ")")

# A class that implements an array of points:
# - AP - array of points.
# The class overloads the += operator,
# which concatenates two arrays of points.
class ArrayPoint:
    # Constructor 2 - creates an empty array
    def __init__(self):
        self.AP = [] # array as a list

    # Method that adds an element to the array
    def Add(self, pt):
        self.AP = self.AP + [pt]

    # Method that returns self.AP array
    def Get(self):
        return self.AP

    # Method that outputs an array of points
    def Print(self, msg):
        print(msg)
        for pt in self.AP:
            pt.Print("")

    # Method that overloads the += operator,
    # the method adds another array to the self.AP array of points
    def __iadd__(self, AP2):
        # 1. Combine lists of two objects
        lst = self.AP + AP2.Get()

        # 2. Create the resulting object
        obj = ArrayPoint()

        # 3. Add list items to obj object
        for t in lst:
            obj.Add(t)

        # Return the resulting object
        return obj

# Testing

# 1. Create the array of points AP1
AP1 = ArrayPoint()
AP1.Add(Point(2, 3))
AP1.Add(Point(4, 7))
AP1.Add(Point(8, 3))
AP1.Print("AP1")

# 2. Create the array of points AP2
AP2 = ArrayPoint()
AP2.Add(Point(-2, 4))
AP2.Add(Point(7, 6))
AP2.Print("AP2")

# 3. Add arrays
AP1 += AP2
AP1.Print("AP1 += AP2")

Result

AP1
('', '=> (', 2, '; ', 3, ')')
('', '=> (', 4, '; ', 7, ')')
('', '=> (', 8, '; ', 3, ')')
AP2
('', '=> (', -2, '; ', 4, ')')
('', '=> (', 7, '; ', 6, ')')
AP1 += AP2
('', '=> (', 2, '; ', 3, ')')
('', '=> (', 4, '; ', 7, ')')
('', '=> (', 8, '; ', 3, ')')
('', '=> (', -2, '; ', 4, ')')
('', '=> (', 7, '; ', 6, ')')

 


Related topics