School Assignment? Project Due Tomorrow? Chat LIVE With A Programming Expert!

Welcome to Dream.In.Code
Become an Expert!

Join 308,426 Programmers for FREE! Get instant access to thousands of experts, tutorials, code snippets, and more! There are 3,239 people online right now. Registration is fast and FREE... Join Now!




> Operator Overloading in Python

parelem
Group Icon



post 2 Apr, 2009 - 03:25 PM
Post #1


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:

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


Simple examples of a few:
CODE
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"
CODE

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.
CODE
    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.


CODE
    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:
CODE
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!

CODE
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:
CODE
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.
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!


Posts in this topic


Fast ReplyReply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 


Lo-Fi Version Time is now: 11/24/09 01:41PM

Live Help!

Be Social

Dream.In.Code RSS Feed Dream.In.Code LinkedIn Group Follow Us On Twitter Fan Us On Facebook

Tutorials

Programming

Web Development

Reference Sheets

Code Snippets

DIC Chatroom

Bye Bye Ads

Monthly Drawing

Thumb Drive

Top Contributors

Top 10 Kudos This Month