Programmers can straightaway use pre-defined operators like +, =, *, >, <, etc. on built-in data types to write programs. However, these operators fail to work in user-defined data types. Therefore, Python comes up with operator loading capability, allowing programmers to redefine operators when working on class objects. To learn more about Self in Python, you can visit our website. Let us learn more about operator overloading in python, binary arithmetic operators, relational operators, and more.
Operators Overloading
Operator overloading allows programmers to extend the meaning of pre-defined operators. Simply put, it provides an expanded definition of what is pre-defined, making it easier for programmers to work seamlessly with both basic data types and user-defined data types.
For instance, operator ‘+’ will add two numbers, either by adding two ranges or combining two lists. You can do the same by overloading the ‘+’ operator with the int and str class. Users may have observed that the identical built-in operator or function exhibits a particular behaviour for components of any specific Python class named operator overloading.
Overloaded Operators
Considering two items depicting a specific class, where you have to insert two objects using the binary ‘+’ operator. Perhaps it will show an error the compiler does not understand how to add. So, we describe an operator mechanism named overloading of the operator. Python includes a magic feature to conduct operator overloading which is immediately activated once paired with this same specific operator.
- For instance, when you are using the ‘+’ operator, the __add__ magical form can automatically describe the ‘+’ operator operation.
- With built-in sets, the Python operator functions well. But for different forms, operators behave accordingly. For example, in two numbers, the ‘+’ operator can apply addition, combine two lists, or merge multiple strings.
- Program to add without overloading the ‘+’ operator.
class circle:
def __init__(object, radius):
object.radius = radius
b1 = circle(10)
b2 = circle(20)
print(b1 + b2)
Output:
TypeError: unsupported operand type(s) for +: ‘circle’ and ‘circle’
Oops! The program is not working and perhaps displays a TypeError. Why? Because we have not yet expanded the code functionalities, and it is operating in built-in groups only. So, how can we enable these operators to run in our device class circles?
Here the “magic techniques” enter the equation. In Python, magic methods include unique procedures that begin and finish with __init__(). The __str__() technique is also another magic method explicitly returning the spring representation of objects.
Program to overload the + operator
class circle:
def __init__(self, radius):
self.radius = radius
def __str__(self):
return "Radius of the circle is: " + str(self.radius)
b1 = circle(10)
print(b1)
Output:
Radius of the circle is: 10
Let us look at one more example to understand overloading better:
Program to subtract two complex numbers without overloading the - operator
class Complex:
def __init__(self):
self.real = 0
self.imag = 0
def setValue(self,real,imag):
self.real = real
self.imag = imag
def display(self):
print(self.real, " + ", self.imag)
C1 = Complex()
C1.setValue(1,2)
C2 = Complex()
C2.setValue(3,4)
C3 =Complex()
C3 = C1 + C2
C3.display()
Output:
TypeError: unsupported operand type(s) for +: ‘Complex’ and ‘Complex’
Program to overload the ‘-‘ operator on a complex object
class Complex:
def __init__(self):
self.real = 0
self.imag = 0
def setValue(self,real,imag):
self.real = real
self.imag = imag
def __sub__(self,C):
Temp = Complex()
Temp.real = self.real - C.real
Temp.imag = self.imag - C.imag
return Temp
def display(self):
print("(", self.real, " - ", self.imag, "i)")
C1 = Complex()
C1.setValue(25,50)
C2 = Complex()
C2.setValue(5,10)
C3 =Complex()
C3 = C1 - C2
print("RESULT = ", end="")
C3.display()
Output:
RESULT = ( 20 - 40 i)
Stream extraction and insertion
Many programming languages like C, C++, and Java have a standard library, allowing programmers to extract strings, numbers, and objects from text input stream with no hassle. Unfortunately, there is no availability for such a library for Python programmers. Python has a stream interface – classes that inherit from io.IOBase that provides facilities for line-oriented input. Perhaps if the user-inputs are arbitrary, the re-module must be the prime consideration.
Increment and Decrement
You may be familiar with increment and decrement operators shown by + + and - - separately if you were acquainted with C, Java, or PHP. But in Python, there seem to be no operators for increment or decrement.
It may sound weird, but we code + = or x = x+ 2 in Python if we are to increase variable value by 2, and we are applying - = or do x = x – 2 to decrease it by 2.
Possible conceptual explanations why Python has no increase and decrement operators could be because the same outcome is obtained through + = or - = seamlessly.
Python code to illustrate Increment Operator
#Increment
a = 5
a +=1
print("Increment Value =", a)
Output:
Increment Value = 6
Python code to illustrate Decrement Operator
#Decrement
a = 5
a -= 1
print("Decrement Value =", a)
Output:
Decrement Value = 4
Assignment operators
The assignment operator, as the name suggests, assigns value to the operand. They are also known as shortcut operators, as they have been used to allocate variable values. The operator allows assigning the value of the operand on the right side of the operator. For instance, a = 4 is a simple attribution operator that attributes the value 4, right to the left variable a.
Note: Do not confuse in-place or shortcut operators. In Python, we have = = rational operators, which may look similar to including assignment operator.
Note the difference:
With the use of the assignment operator, the variable gets assigned with a value, 4.
# Assignment Operator
a = 4
In a relational operator, the variable checks the condition and displays the output in the Boolean value. If the expression condition gets satisfied, the code output is True, else False.
# Relational Operator
a = = 4
Binary Arithmetic Operators
Arithmetic operators like addition, subtraction, multiplication, floor division, exponent (or power), and modulus are there by default in all the programming languages. In Python, all these arithmetic operators are binary, showing they are running on two controllers. Simply put, they run on two operators.
Programmers apply these operators on numbers as well as on variables to perform corresponding operations. The regular primary concern level is given to binary arithmetic operations. Notice that certain non-numeric forms of these operations often occur. Besides the power user, just two components are available, one for multiple operators and one category for additive operators.
Let’s understand binary arithmetic operators with the help of an example. Assigning a = 50, and b = 100, we get the following outputs.
Python Arithmetic Operators | Operation | Example | Output |
---|
+ | Addition – adds the operands | print(a+b) | 150 |
- | Subtraction – subtracts operand on the right from the operands on the left of the operator | print(a-b) | -50 |
* | Multiplication – Multiplies the operands | print(a*b) | 5000 |
/ | Division – Divides operand on the left side of the operator with the operand on the right, and returns the quotient as output. | print(b/a) | 2.0 |
% | Modulus – Divides operand on the left side of the operator with the operand on the right, and returns the remainder as output. | print(b%a) | 0 |
// | Floor Division – Divides operand on the left side of the operator with the operand on the right, and returns the quotient without any decimal point. | print(b//a) | 2 |
** | Exponent – It raises the operand on the left side of the operator with the operand on the right performing exponential calculation. | print(a**b) | 50100 |
Relational Operators
Relational operators in Python are also often called comparison operators. These should measure and test the relationship between the operands on both sides. A Boolean value occurs in the comparison performance. These operators are being used to discover the association between two operands in the program. They are useful for the comparison of the values. It responds either True or False, depending on the condition.
Let us understand relational operators with the help of an example. Assigning a = 50, and b = 100, we get the following outputs.
Python Relational Operators | Description | Example | Output |
---|
== | Returns True if the values at both operands on the left and the value of operator and operand are equal. | print(a == b) | False |
!= | Returns True if the values at both operands on the left and the value of operator and operand are unequal. | print(a != b) | True |
> | Returns True if the values at operand on the left are greater than the value of operator are equal. | print(a >= b) | False |
< | Returns True if the values at operand on the left are lesser than the value of operator are equal. | print(a <= b) | True |
>= | Returns True if the values at operand on the left are greater than or equal to the value of operator are equal. | print(a >= b) | False |
<= | Returns True if the values at operand on the left are lesser than or equal to the value of operator are equal | print(a <= b) | True |
Array
An array is a set of similar forms of components. Simply put, it stores many data of the same type collectively. They may be helpful if there is a need for exploitation for such data types. The sorting of items stored in the array can be, however, extensively restricted by the users.
To create an array, we need to import an array module.
Here is a code where we have created an array of type int. Notice the letter i is the type code.
import array as ar
vals = ar.array('i', [5, 4, 3, 2, 1])
print(vals)
Output:
array(‘i’, [5, 4, 3, 2, 1])
Here is a code where we have created an array of type float. Notice the letter d is the type code.
import array as ar
vals = ar.array('d', [5.1, 4.2, 3.3, 2.4, 1.5])
print(vals)
Output:
array(‘d’, [5.1, 4.2, 3.3, 2.4, 1.5])
Bitwise operators
Bitwise operators are operators in Python running at the binary level. That means these operators appear at the binary numbers or sections of an integer specifically. Much of this seems terrifying, but it is easy for bit operations. Compared with other operating systems, they are relatively fast since these procedures can be performed straightaway by the processor.
Rather than words, bitwise operators are merely labelled with odd signs, making them look less wordy than you could see in Python. Bitwise operators include:
- Bitwise AND(&)
- Bitwise OR(|)
- Bitwise XOR(^)
- Bitwise NOT(~)
- Shift Left(<<)
- Shift Right(>>)
Overloaded Operators Restrictions
When overloading operators, programmers are free to overload any arithmetic operators except the = operator. The thumb rule says: Never try to overload the = = operator, because it becomes strenuous, and almost impossible to verify the test, whether the two objects are the same. Say you have an object x, which is from a custom class or is an integer, and you want to see if x is the number 500. If you set x = 500, then later test if x is 500, you will get False because of the way Python caches numbers.
Boolean negation operator
When there is a need to reverse the meaning of an operand, we use the Boolean negation operator using the keyword not. This operator works by merely inverting the value of its an operand. If the expression you have to write is True, placing the keyword ‘not’ before it will return False, and vice versa.
Let’s understand with the help of an example.
classroom = ['Alex', 'Bella', 'Christopher', 'Diana']
if 'Bella' not in classroom:
print("Present")
else:
print("Absent")
Output:
Absent
N.B: In the defined list named classroom, we had four students attending the class. When we checked whether “Bella” is present in the list or not, we got the output as Absent because she is present. Simply amazing how using the not keyword can reverse the entire meaning of the expression.
Function Overloading in Python
One of the perks of using Python is to overload functions, besides overloading operators. Python allows to overload functions like long(), float(), abs(), and hex(). We may alter the importance of a Python operator inside the category by overloading the operator. Programmers can use these functions to convert a value of a user-defined type (object) to a value of another type.
Program to overload hex(), oct(), and float() functions.
class Number:
def __init__(self, num):
self.num = num
def display(self):
return self.num
def __abs__(self):
return abs(self.num)
def __float__(self):
return float(self.num)
def __oct__(self):
return float(self.num)
def __hex__(self):
return hex(self.num)
def __setiem__(self, num):
self.num = num
N = Number(-20)
print("Num is : ", N.display())
print("Abs(Num) is : ", abs(N))
N = abs(N)
print("Converting to Float . . . . . . Num is : ", float(N))
print("The Equivalent of Num in Hexadecimal is : ", hex(N))
print("The Equivalent of Num in Octal is : ", oct(N))
Output:
Num is: -20
Abs(Num) is : 20
Converting to Float . . . . . . Num is : 20.0
The Equivalent of Num in Hexadecimal is : 0x14
The Equivalent of Num in Octal is : 0o24
Conclusion
Coders can run without overloading operators as well. With operator and functional overloading, it is easy to write efficient codes in basis and built-on data types. Perhaps you will see the real capabilities of operator overloadong in scientific computing while computong the representation of mathematical objects with no hassle. Otherwise, it would make the computation complex, time-consuming, and demanding.