Page 1 of 1

Operator Overloading in Python

#1 parelem  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 1
  • View blog
  • Posts: 13
  • Joined: 02-March 09

Posted 02 April 2009 - 04:25 PM

Built in data structures are nice, but have you ever needed or wanted to use something that isn't built in? Have you ever wanted to use built in operators on your data structures? Operator overloading allows you to do so.

In Python the following are operators:

+	   -	   *	   **	  /	   //	  %
<<	  >>	  &	   |	   ^	   ~
<	   >	   <=	  >=	  ==	  !=	  <>



Simple examples of a few:
2 + 1
2*1
2.0-1.0
2/3+1/4


Hey wait a minute what was that last one? 2/3+1/4, according to Python, this is 0! That's not what we wanted now was it? We would like to work with rational numbers in python, so we'll begin by creating a new class called "Rational"
class Rational(object):
	def __init__(self, numerator=0, denomiator=1):	
		self.numer = numerator
		self.denom = denomiator
		self.fixSign()	 #will explain later
		self.reduce()	 #will explain later


Here I have defined the class and put in an initializing function, what __init__ does is creates an object with the initial parameters if no parameters are supplied for the object. If parameters are supplied, the object will be created with the supplied parameters.

Next we will want to overload some operators so we can use our new class.
	def __add__(self,rhs):  #self and rhs are Rational objects
		n1 = self.numer	#numerator of the self object
		d1 = self.denom	#denominator of the self object
		n2 = rhs.numer	 #numerator of the rhs object
		d2 rhs.denom	   #denominator of the rhs object
		r = Rational(d2*n1+d1*n2,d1*d2)	#creates a new object with d2*n1+d1*n2 as the numerator, and d1*d2 as the denominator
		return r
	def __sub__(self,rhs):
		n1 = self.numer	#numerator of the self object
		d1 = self.denom	#denominator of the self object
		n2 = rhs.numer	 #numerator of the rhs object
		d2 = rhs.denom	   #denominator of the rhs object
		r = Rational(d2*n1-d1*n2,d1*d2)	#creates a new object with d2*n1-d1*n2 as the numerator, and d1*d2 as the denominator
		return r


__add__ and __sub__ are the Python names used for the + and - operators. Now that we have these operators overloaded, we can use + and - on Rational objects just as we would on integers or floats.

Before we get to using our operators, let's first create a few more functions that make life easier.


	def gcd(self,a,b):
		if b == 0:
			return a
		return self.gcd(b,a%b)
	def fixSigns(self):	#takes - sign out of the denominator
		if self.denom <0:	#check if denominator is negative
			self.numer = -self.numer	#switch sign of numerator
			self.denom = -self.denom	#switch sign of denominator
	def reduce(self):	#reduce the fraction
		d = 1
		if self.denom != 0 and self.numer !=0:	  #make sure the fraction != 0
			d = self.gcd(self.numer, self.denom)	#finds the greatest common denominator in order to reduce 
		if d > 1:		#reduce away!
			self.numer /= d
			self.denom /= d
	def __str__(self):			#rules for printing our objects
		s = "%d /% d" % (self.numer,self.denom)
		return s


gcd finds the greatest common denominator of the numerator and denominator
fixSigns is used to remove negatives from the denominator
reduce reduces the fraction by using the greatest common denominator function
__str__ gives a rule on how we want our object printed



Complete class:
class Rational(object):
	def __init__(self, numerator=0, demoniator=1):
		self.numer = numerator
		self.denom = demoniator
		self.fixSign()
		self.reduce()
	def __add__(self,rhs):  #self and rhs are Rational objects
		n1 = self.numer	#numerator of the self object
		d1 = self.denom	#denominator of the self object
		n2 = rhs.numer	 #numerator of the rhs object
		d2 rhs.denom	   #denominator of the rhs object
		r = Rational(d2*n1+d1*n2,d1*d2)	#creates a new object with d2*n1+d1*n2 as the numerator, and d1*d2 as the denominator
		return r
	def __sub__(self,rhs):
		n1 = self.numer	#numerator of the self object
		d1 = self.denom	#denominator of the self object
		n2 = rhs.numer	 #numerator of the rhs object
		d2 = rhs.denom	   #denominator of the rhs object
		r = Rational(d2*n1-d1*n2,d1*d2)	#creates a new object with d2*n1-d1*n2 as the numerator, and d1*d2 as the denominator
		return r
	def gcd(self,a,b):
		if b == 0:
			return a
		return self.gcd(b,a%b)
	def fixSigns(self):	#takes - sign out of the denominator
		if self.denom <0:	#check if denominator is negative
			self.numer = -self.numer	#switch sign of numerator
			self.denom = -self.denom	#switch sign of denominator
	def reduce(self):	#reduce the fraction
		d = 1
		if self.denom != 0 and self.numer !=0:	  #make sure the fraction != 0
			d = self.gcd(self.numer, self.denom)	#finds the greatest common denominator in order to reduce 
		if d > 1:		#reduce away!
			self.numer /= d
			self.denom /= d
	def __str__(self):			#rules for printing our objects
		s = "%d /% d" % (self.numer,self.denom)
		return s


Now that we have all this done, we can start using our class and operators. Let's test!

from rational import *
def main():
	r1 = Rational(4,9)
	r2 = Rational(2,7)
	r3 = Rational(1,3)
	r4 = Rational(4,6)


	#use our __str__ function
	print "r1: ", r1
	print "r2: ", r2
	print "r3: ", r3
	print "r4: ", r4

	#use our operators

	print "r2-r1: ", (r2-r1)
	print "r1+r3: ", (r1+r3)

	r5 = r3+r4
	print r3, " + ", r2, " = ", r3

	a,b,c,d = 1,4,3,6
	print "%d/%d + %d/%d = %s" %(a,b,c,d,Rational(a,b) + Rational(c,d))
	print "%d/%d - %d/%d = %s" %(a,b,c,d,Rational(a,b) - Rational(c,d))

if __name__ == "__main__":
	main()


Python output:
r1:  4 / 9
r2:  2 / 7
r3:  1 / 3
r4:  2 / 3
r2-r1:  -10 / 63
r1+r3:  7 / 9
1 / 3  +  2 / 7  =  1 / 3
1/4 + 3/6 = 3 / 4
1/4 - 3/6 = -1 / 4


Now that we've overloaded the + and - operators, we can easily continue to overload more as needed. Perhaps you'd like to overload == (__eq__) or != (__ne__), you can do so by the same method.

Is This A Good Question/Topic? 1
  • +

Replies To: Operator Overloading in Python

#2 desirocks  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 9
  • Joined: 12-June 09

Posted 20 June 2009 - 11:32 PM

First of all let me thank you for providing a great tutorial on operator overloading in python. I would like to see more python tutorials in this forum. In fact we should have a separate section for python tutorials.

I wanted to know the significance of the following code


r5 = r3+r4
print(r3, " + ", r2, " =", r3)




Now the result that you have printed is 1/3 + 2/7 = 1/3. This is just a print statement. I also do not understand the significance of r5 which eventually will be 1. but we do not use it anywhere.

It would be great if anybody could explain me a bit in detail.

Thanks in advance.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1