Chapter 11: Objects and Classes
Discover how Python implements Object-Oriented Programming (OOP). Understand how every standard data type is an object, model real-world concepts using class blueprints, initialize attributes, and design custom methods to mutate state.
Why Do We Need Objects and Classes?
In programming, duplicate code blocks are highly inefficient and hard to maintain. A class is a reusable blueprint or layout that defines custom data attributes and helper functions, and an object is a unique instance of that class. Object-Oriented Programming (OOP) makes it easy to write clean, modular, and reusable code by grouping data attributes and methods directly within objects.
11.1 Objects and Methods
In Python, absolutely everything is an object. Each object possesses a type (its class), an internal representation, and a set of methods that you can invoke to interact with it.
Consider a list of ratings: Ratings = [10.0, 8.5, 9.0, 7.0, 8.0]. The list is an instance of the list type. We call methods on it by appending a dot (.) and the method name:
ratings = [10.0, 8.5, 9.0, 7.0, 8.0]
ratings.sort() # Mutates ratings in-place to ascending order
ratings.reverse() # Mutates ratings in-place by reversing order
Observe the ratings array elements in memory. Call methods to mutate the list state in-place with animations.
11.2 Blueprints and Instances (The Box Analogy)
To define your own object types, use the class keyword. A class acts as a template or skeleton. It uses a special constructor function called __init__ to initialize custom data attributes, using the self parameter to refer to the newly created instance.
class Circle(object):
def __init__(self, radius, color):
self.radius = radius
self.color = color
class Rectangle(object):
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
Choose a class definition, select parameters, and instantiate the class. Watch the constructor populate a self object container box and draw the shape dynamically.
11.3 Custom Methods & Mutations
Methods are functions defined inside a class that interact with and change the instance's data attributes. Self is implicitly passed by Python to allow the method to access local fields.
Let's define an add_radius(r) method that increases the radius of our circle object:
class Circle(object):
def __init__(self, radius, color):
self.radius = radius
self.color = color
def add_radius(self, r):
self.radius = self.radius + r
return self.radius
# Instantiate and increment radius
red_circle = Circle(4, 'red')
print("Initial radius:", red_circle.radius)
red_circle.add_radius(3)
print("Updated radius:", red_circle.radius)
Initialize a circle, select a modifier value r, and invoke the method. Observe the execution path modifying the attributes inside the object.
11.4 Object Introspection (dir())
The built-in dir() function returns a list of all data attributes and methods associated with an object. Double-underscore attributes (e.g. __init__, __str__) are internal properties that Python manages automatically. The regular-looking items are the public attributes and methods you can use.
class SimpleObject:
def __init__(self):
self.name = "Data Science Object"
def greet(self):
return "Hello World!"
obj = SimpleObject()
# Introspect attributes and methods
attributes = dir(obj)
# Print public attributes (excluding double underscore system methods)
public_attrs = [attr for attr in attributes if not attr.startswith('__')]
print("All Attributes:\n", attributes)
print("\nPublic Attributes:\n", public_attrs)
Try Introspection: Click "Try It Yourself" to run the dir() function. Notice how Python lists both the internal properties and the custom greet method you defined.
Select an object instance, toggle internal system attributes, and invoke dir(object) to inspect its properties.
Practice Quiz
Validate your understanding of classes, constructors, methods, and introspection in Python.