Lecture Notes
Introduction to Programming and Algorithm Design (COP-1000)

Classes and methods

This chapter discusses how to incorporate attributes into classes as instance variables, and functions as methods of the class.


Object-oriented features

  • Python supports object-oriented programming (OOP)
  • Object-oriented programs have these characteristics:

The programs are made up of object definitions and function definitions, and most of the computation is expressed in terms of operations on objects.

Each object definition correspond to some object or concept in the real world, and the functions that operate on that object correspond to the ways real-world objects interact

  • OOP uses syntax that makes it easy to associate objects with the functions that operate on them, by rewriting these functions as methods
  • Methods are like functions but with two differences:
    • Methods are defined inside a class definition
    • The syntax for invoking a method is different from that for calling a function

Printing objects

  • We can rewrite the printTime function from the previous chapter as a method of a Time object by including its definition within the class definition:

    class Time:

       def showTime(self):
          "Display time in 24-hour format."
          print "%02d:%02d:%02d" % \
              (self.hours, self.minutes, self.seconds)
     
  • By convention, the first parameter of a Python method is always named self if the method will reference any of the object's attributes
  • Since showTime is now a method of the class Time, all objects instantiated from Time will have a method showTime, which we can invoke with dot notation:

    noon = Time()
    noon.hours = 12
    noon.minutes = 0
    noon.seconds = 0
    noon.showTime()
     
  • See example program time14_1.py

Another example

  • Here's a version of class Time that implements the increment method: time14_2.py
    • Reduction of time object to proper format implemented as separate method reduceTime

A more complicated example

  • This version of class Time adds the after methods to compare two Time objects: time14_3.py
    • Compares argument to self
    • Uses convertToSeconds method to simplify logic

Optional arguments

  • You can give an parameter a default value with the syntax:

       parameter_name = default_value
     
  • In the example program time14_4.py, the argument in the increment method is given the default value of 1; if the increment method is called with no argument, the default value is assigned to the parameter

The initialization method __init__

  • A special method, called the initialization method can be included in a class definition; its syntax is:

        def __init__(self, other_parameters):
            body
     
  • The name of the method is preceded and followed by two underscore characters
  • The initialization method is invoked automatically when the object is created
  • Use the initialization method to validate and initialize instance variables, as in this example: time14_5.py

The __str__ method

  • The __str__ method is a special method that is automatically invoked by Python whenever it needs to print the object
  • The __str__ method should return a string representation of  the object
  • Here is the Point class, rewritten to in a more OO style: point14_1.py
    • Includes method __str__, which returns a Point object as a string; it is automatically invoked in a print statement
  • When you write a class, always include the  __init__ and __str__ methods
  • Here is another example the revised Time class: time14_6.py

Operator overloading

  • Some languages, like C++, let you define new operations on user-defined types using operators, rather than method; this is called operator overloading
  • For example, to define the addition operator (+) to work on Point objects, we would include a method named __add__ that defines how Points are to be added
  • If p1 and p2 are Point objects, then the expression

        p1 + p2

    would be understood by the Python interpreter to invoke the __add__ method:

        p1.__add__(p2)
     
  • Here is an example: point14_2.py
  • And here is another example: time14_7.py
  • Other operators can be overloaded, also; see Python documentation for details:

       http://docs.python.org/reference/datamodel.html#specialnames

Type-based dispatch

  • Operator overloading works fine if you want to add two time objects, but if you want to allow clients of your class to also add an integer to a time object (to increment it), you will need to use type-based dispatch to invoke the proper method
  • Type-based dispatch uses the built-in function isinstance to determine if an object is a member of a class:

def __add__(self, other):
   if isinstance(other, Time):
      return self.add_time(other)
   else:
      return self.increment(other)

  • The proper method is called, based on the type of the argument used by the client, so if t1 and t2 are two Time objects, then:

t1 = t1 + t2          # add t2 to t1
t1 = t1 + 5           # adds 5 seconds to t1

  • Unfortunately, this works only if the Time object is the left-hand operand; there is a __radd__ method that allows the addition operator to be overloaded when an object is used as the right-hand operator:

def __radd__(self, other):
   return self.__add__(other)

  • See time14_8.py that demonstrates type-based dispatch and overloaded addition.

Polymorphism

  • Functions that can work with several types are called polymorphic
  • Polymorphism promotes software reuse
 Updated: 12.13.2010