For every operator sign, there is an underlying mechanism. This underlying mechanism is a special method that will be called during the operator action. This special method is called
magical method. For every arithmetic calculation like +, -, *, /, we require 2 operands to carry out operator functionality.
Examples:
‘+’ ? ‘__add__’ method
‘_’ ? ‘__sub__’ method
‘*’ ? ‘__mul__’ method
As the article is limited to multiplication functionality, we will see about multiplication procedure here. To perform the multiplication functionality, we have to tie up the operator sign to either left/right operand. Before, going to
__rmul__
method, we will see about
__mul__
method, which helps us to understand multiplication functionality vividly.
__mul__()
Let’s take an expression
x*y
where x is an instance of a class A. To perform the
__mul__
method, the operator looks into the class of left operand(x) for the present of __mul__ i.e., operator(*) will check the class A for the presence of ‘
__mul__
’ method in it. If it has
__mul__
method, it calls
x.__mul__(y)
. Otherwise, it throws the ‘
TypeError: unsupported operands’ error message.
Example 1:
Python3 1==
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(f * b)
Output:
TypeError, unsupported operand type(s) for *: 'Foo' and 'Bar'
In the above example, the first operand is f and its class Foo(). As Foo() has no
__mul__
method, it doesn’t understand how to multiply. So, it will show up TypeError message. If we check the other class Bar(), even it has no
__mul__
method. So, even if we reverse the multiplication to (b*f), it will throw the same error
Example 2: Lets add the __mul__ method in Foo class.
Python3 1==
class Foo(object):
def __init__(self, val):
self.val = val
def __mul__(self, other):
return Foo(self.val * other.val)
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(f * b)
Output:
Foo 30
As it is already mentioned, the operator by default looks into the left operand’s class, and here it finds the __mul__ method. Now it knows what to do and resulted 30
f.__mul__(b) = 5.__mul__(6)
. If we reverse the multiplication to (b*f), it throws up the issue again, as it looks into left operand’s class(Bar()) which doesn’t have any
__mul__
method.
b.__mul__(f)
will throws the issue as b's class Bar() doesn't have
__mul__
method.
__rmul__
A slight difference between
__mul__
and
__rmul__
is, Operator looks for
__mul__
in left operand and looks for
__rmul__
in right operand. For example, x*y. Operator looks for
__rmul__
method in the y’s class definition. If it finds the
__rmul__
method, it will show up with the result, otherwise throws the
TypeError error message
Example 1: Let's take the above example with a small modification.
Python3 1==
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __rmul__(self, other):
return Bar(self.val * other.val)
def __str__(self):
return "Bar [% s]" % self.val
# Driver code
f = Foo(5)
b = Bar(6)
print(f * b)
Output:
Bar 30
In the above example, it assumes f*b as
b.__rmul__(f)
as
__rmul__
method is present in Bar() class of the instance b. If we reverse the multiplication to (b*f). The notation will be
f.__rmul__(b)
. If it doesn’t have
__rmul__
method, it can't understand what to notate and throws up TypeError message.'
These type of operators, that require 2 operands, it will by default carry both
__mul__
and
__rmul__
method. To perform multiplication with both normal and reverse multiplication, see the below example.
Example 2:
Python3 1==
class Foo(object):
def __init__(self, val):
self.val = val
def __str__(self):
return "Foo [% s]" % self.val
class Bar(object):
def __init__(self, val):
self.val = val
def __rmul__(self, other):
return Bar(self.val * other.val)
def __mul__(self, other):
return self.__rmul__(other)
def __str__(self):
return "Bar [% s]" % self.val
# Driver Code
f = Foo(5)
b = Bar(6)
print(b * f)
print(f * b)
Output:
Bar [30]
Bar [30]
Similar Reads
re.subn() in Python
re.subn() method in Python is used to search for a pattern in a string and replace it with a new substring. It not only performs the replacement but also tells us how many times the replacement was made. We can use this method when we need to replace patterns or regular expressions in text and get a
3 min read
re.match() in Python
re.match method in Python is used to check if a given pattern matches the beginning of a string. Itâs like searching for a word or pattern at the start of a sentence. For example, we can use re.match to check if a string starts with a certain word, number, or symbol. We can do pattern matching using
2 min read
re.search() in Python
re.search() method in Python helps to find patterns in strings. It scans through the entire string and returns the first match it finds. This method is part of Python's re-module, which allows us to work with regular expressions (regex) simply. Example:Pythonimport re s = "Hello, welcome to the worl
3 min read
Python - re.compile()
In Python, re.compile() from the re module creates a regex object from a regular expression pattern. This object lets you perform operations like search(), match(), and findall(). In this article, we will understand about re.compile() method.Pythonimport re # Compile the pattern pattern = re.compile
2 min read
re.compile() in Python
The re.compile() method in Python is used to compile a regular expression pattern into a regex object. Compiling a pattern makes it more efficient when we need to use the same pattern several times, as it avoids re-compiling the pattern each time. Letâs look at how re.compile() works and when we sho
3 min read
zlib.crc32() in python
With the help of zlib.crc32() method, we can compute the checksum for crc32 (Cyclic Redundancy Check) to a particular data. It will give 32-bit integer value as a result by using zlib.crc32() method. Syntax : zlib.crc32(s) Return : Return the unsigned 32-bit checksum integer. Example #1 : In this ex
1 min read
re.findall() in Python
re.findall() method in Python helps us find all pattern occurrences in a string. It's like searching through a sentence to find every word that matches a specific rule. We can do this using regular expressions (regex) to create the pattern and then use re.findall() to get a list of matches.Let's say
2 min read
Underscore (_) in Python
In Python, underscores have different meanings depending on how they are used. The single underscore (_) and double underscore (__) each serve specific purposes. They are commonly used in different situations, such as for variable names, method names, and more. Single UnderscoreSingle underscore (_)
5 min read
Shutil Module in Python
Shutil module offers high-level operation on a file like a copy, create, and remote operation on the file. It comes under Pythonâs standard utility modules. This module helps in automating the process of copying and removal of files and directories. In this article, we will learn this module. Copyin
8 min read
eval in Python
Python eval() function parse the expression argument and evaluate it as a Python expression and runs Python expression (code) within the program.Python eval() Function SyntaxSyntax: eval(expression, globals=None, locals=None)Parameters:expression: String is parsed and evaluated as a Python expressio
5 min read