Lesson 28 Classes and Methods Python Mini-Course University of Oklahoma Department of Psychology 1 Python Mini-Course: Lesson 28 6/17/09 Lesson objectives 1. Create methods inside class definitions 2. Call methods using function syntax and method syntax 3. Create custom __init__ and __str__ methods 4. Use operator overloading 2 Python Mini-Course: Lesson 28 6/17/09 Encapsulation Data and behaviors are packaged together The object only reveals the interfaces needed to interact with it Internal data and behaviors can remain hidden 3 Python Mini-Course: Lesson 28 6/17/09 Encapsulating the Time class Instead of using functions, we want to use methods Move the functions inside the class definition 4 Python Mini-Course: Lesson 28 6/17/09 The print_time() method class Time(object): … def print_time(self): """ Print the time in hour:minute:second format. """ print '%02d:%02d:%02d' % \ (self.hour, self.minute, self.second) 5 Python Mini-Course: Lesson 28 6/17/09 Calling a method Using function syntax t1 = Time(2,35) Time.print_time(t1) Using method syntax t1.print_time() 6 Python Mini-Course: Lesson 28 6/17/09 Converting the other functions to methods The valid_time method The increment method The add_time method 7 Python Mini-Course: Lesson 28 6/17/09 The valid_time method class Time(object): ... def valid_time(self): validity = True # All values must be at least zero if self.hour < 0 or self.minute < 0 \ or self.second < 0: validity = False # Minute and second must be base 60 if self.minute >= 60 or self.second >= 60: validity = False return validity 8 Python Mini-Course: Lesson 28 6/17/09 The increment method class Time(object): ... def increment(self, t2): # Check the input arguments if type(t2) != Time: raise AttributeError, \ 'invalid argument passed to Time.increment()' if not t2.valid_time(): raise ValueError, \ 'invalid Time object passed to Time.increment()' # Add the times self.hour += t2.hour self.minute += t2.minute self.second += t2.second 9 Python Mini-Course: Lesson 28 6/17/09 The add_time method class Time(object): ... def add_time(self, t2): # Add the times new_time = Time() new_time.hour = self.hour + t2.hour new_time.minute = self.minute + t2.minute new_time.second = self.second + t2.second # Return the sum return new_time 10 Python Mini-Course: Lesson 28 6/17/09 Using the Time class t1 = Time(0,0,30) t2 = Time(1,0,45) t1.increment(t2) t1.print_time() t3 = t1.add_time(t2) t3.print_time() t4 = Time.add_time(t1, t2) t4.print_time() 11 Python Mini-Course: Lesson 28 6/17/09 Improving the Time class Problems: 1. Formatting 1. Minutes and seconds should always be less than 60 2. Printing is awkward 3. Adding times is awkward Solutions: see time_oop1.py 12 Python Mini-Course: Lesson 28 6/17/09 Keeping the right format class Time(object): ... def adjust_base_60(self): # Increment minutes as necessary and adjust seconds self.minute += self.second // 60 self.second = self.second % 60 # Increment hours as necessary and adjust minutes self.hour += self.minute // 60 self.minute = self.minute % 60 13 Python Mini-Course: Lesson 28 6/17/09 Controlling access to attributes class Time(object): ... def set_time(self, hour=0, minute=0, second=0): self.hour = hour self.minute = minute self.second = second self.adjust_base_60() 14 Python Mini-Course: Lesson 28 6/17/09 The __str__ method class Time(object): … def __str__(self): """ Return the time in hour:minute:second format. """ return '%02d:%02d:%02d' % \ (self.hour, self.minute, self.second) 15 Python Mini-Course: Lesson 28 6/17/09 The __str__ method The __str__ method is a special method that is called by the str() and print commands t1 = Time(2,45) str(t1) print t1 16 Python Mini-Course: Lesson 28 6/17/09 Why does this work? In Python, the most basic class, the object class, defines the __str__ method Time is a sub-class of the object class, and it inherits this behavior By defining our own __str__ method we override the base class method This is polymorphism 17 Python Mini-Course: Lesson 28 6/17/09 Operator overloading We can also define how a class responds to standard operators such as +, -, etc. This is called operator overloading 18 Python Mini-Course: Lesson 28 6/17/09 The __add__ method class Time(object): ... def __add__(self, other): return self.add_time(other) def add_time(self, t2): new_time = Time() new_time.hour = self.hour + t2.hour new_time.minute = self.minute + t2.minute new_time.second = self.second + t2.second new_time.adjust_base_60() return new_time 19 Python Mini-Course: Lesson 28 6/17/09 Using the __add__ method t1 = Time(0,0,30) t2 = Time(1,0,45) t3 = t1 + t2 print t3 print t1 + t2 20 Python Mini-Course: Lesson 28 6/17/09 Type-based dispatch Allow us to use different types of arguments for the same method (or function) 21 Python Mini-Course: Lesson 28 6/17/09 class Time(object): ... def increment(self, t2): # Check the input arguments if type(t2) == Time: # Add the times self.hour += t2.hour self.minute += t2.minute self.second += t2.second elif type(t2) == int: # Increment the seconds self.second += t2 else: raise AttributeError, \ 'invalid argument passed to Time.increment()' self.adjust_base_60() 22 Python Mini-Course: Lesson 28 6/17/09 For more practice, try Think Python. Exercise 17.3, Exercise 17.4, Exercise 17.5, Exercise 17.6, exercise) 23 Python Mini-Course: Lesson 28 Chap 17 page page page page 165 166 167 169 (debugging 6/17/09 Assignment Think Python. Chap 18 Read text Type in and run code as you go (save as poker.py) Do Exercises 18.2 and 18.3 in text 24 Python Mini-Course: Lesson 28 6/17/09