Intro to Classes in Python

Published 9/13/2016

OOP and Classes

Quick Note

This tutorial is part of the Python Basic Resources 4-part series produced by Galvanize.

This tutorial moves very fast. If you would like a slower, more in-depth intro to Python, we suggest you take our Intro to Python Evening Course. It's the perfect way to become familiar with Python + gain experience using Python to solve challenging problems.

Prerequisites

This web tutorial follows the Jupyter notebook found on GitHub. If you are viewing it using GitHub, then you cannot execute the cells that contain Python code. To view and run this notebook you'll need to install Jupyter on your computer before you continue. See these installation instructionsfor help!

Overview

From wikipedia: "Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which are data structures that contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods."

Object-oriented programming has many benefits (see encapsulation, polymorphism, and inheritance in the wiki), but it also kind of matches how we think about the world. The world is composed of objects, where objects can be people, houses, cars, buildings, etc. These objects have some properties about them (i.e. they contain data), and they can do things (i.e. they have methods that can be applied). Object oriented programming approaches a programming problem by using objects that interact with each other, much like they do in the real world.

Some Terminology

1.) Class - used to refer to the abstract concept of an object.
2.) Object - An actual instance of a class.
3.) Instance - What Python returns when you tell it to create a class.
4.) self - Inside of a class, a variable for the instance/object being accessed (i.e. it holds a reference to the instance/object of that class).
5.) attribute / field / property - A property or piece of data that a class has, stored in a variable. All attributes/fields/properties within a class are assigned via self.
6.) method / procedure - A block of code that is accessible via the class, and typically acts on or with the classes attributes/fields/properties. All methods/procedures within a class are created via def. (they are really just functions).

From here on out, I will treat attribute, field, and property as interchangeable, and I'll do the same with method and procedure.

Defining a Class

Much like defining a function, there is a common format to defining a class. It is almost exactly the same as defining a function, but we replace def with class. That is, we write class, then the name of the class that we are defining, followed by a set of parentheses, and finally a colon. After the colon is an indented block of code that we use to define the class attributes and methods. One subtle difference is that with functions, the standard is to name these beginning in lowercase and seperating words with underscores (snake_case), while with classes, the standard is to name these beginning in uppercase, and not separate words at all (CamelCase).

class MyClass(): 
    # Attributes and methods go in here.

Instantiation

Instantiation is just a fancy word for saying that we're going to create an instance of a particular class.

my_class = MyClass() # Now we have my_class as an instance of MyClass

Inner Workings

Inside of a class, we can have both attributes and methods. We can then think of these attributes and methods as belonging to the class, and they become accessible via any instances of the class (through dot notation, which we'll get to in a second). Inside of the class, all of these attributes and methods are set and retrieved via self. Let's dive in...

The _init_() method

Almost every class you ever write will have an _init_() method. This method gets called every time that you create a new instance of a class, and handles any kind of setup that the class may require. Setup typically just involves assigning values to variables, which we can do with or without passing values in.

In [1]:
class MyClass(): 
    
    def __init__(self):
        # No values have been passed in here. 
        self.meetup_name = 'Data Science'

my_class = MyClass()
print my_class.meetup_name # Note the dot notation here to access the 'meetup_name' field. 
Data Science
In [2]:
class MyClass(): 
    
    def __init__(self, meetup_name):
        # Here we passed the value that will be assigned in. Note the assignment using self. 
        self.meetup_name = meetup_name

my_class = MyClass('Data Science')
print my_class.meetup_name
Data Science
What happens if we don't use self?
In [3]:
class MyClass(): 
    
    def __init__(self, meetup_name):
        # Here we passed the value that will be assigned in. 
        meetup_name = meetup_name

my_class = MyClass('Data Science')
print my_class.meetup_name
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-ee58f148da2d> in <module>()
      6 
      7 my_class = MyClass('Data Science')
----> 8 print my_class.meetup_name

AttributeError: MyClass instance has no attribute 'meetup_name'

Magic Methods

The _init_() method is a special type of magic method. Magic methods allow you to build a lot of functionality into your classes, most of which allow you to interact with your classes using a lot of the built-in functions. I don't use these often in my day to day, but the _len_(), __str\(), __repr() ones are pretty common. The first lets you use the len() function on instances of your class, and the second to allow you to define a readable display of an instance of your class (used when printing or applying the str() function).

Other Methods

We can of course define other methods of our classes...

In [5]:
class MyClass(): 
    
    def __init__(self, meetup_name='Data Science'):
        # Here we passed the value that will be assigned in. 
        self.meetup_name = meetup_name
        self.meetup_questions = []
        self.meetup_answers = []
    
    def add_question(self, question):
        # Note the referal to the meetup_questions field via self. 
        self.meetup_questions.append(question)
    
    def add_answer(self, answer): 
        self.meetup_answers.append(answer)
        
my_class = MyClass()
print my_class.meetup_name
print my_class.meetup_questions
print my_class.meetup_answers
Data Science
[]
[]
In [6]:
my_class.add_question('What question should I ask?')
my_class.add_answer('Think of anything!')
In [7]:
print my_class.meetup_name
print my_class.meetup_questions
print my_class.meetup_answers
Data Science
['What question should I ask?']
['Think of anything!']

Using Multiple Objects

That's the whole point of them, right?

In [9]:
class Member(): 
    
    def __init__(self, name): 
        self.name = name
        self.questions_asked = []
        self.question_answers = []
    
    def add_question(self, question): 
        self.questions_asked.append(question)
    
    def add_answer(self, question): 
        self.question_answers.append(question)
        
class MyClass(): 
    
    def __init__(self, name='Data Science'): 
        self.name = name
        self.members = []
    
    def num_questions_asked(self): 
        total_questions = 0
        for member in members: 
            total_questions += len(member.questions_asked)
        
        return total_questions
        
    def num_questions_answered(self): 
        total_questions = 0
        for member in members: 
            total_questions += len(member.question_answers)
        
        return total_questions
In [10]:
# Create some members. 
josh = Member('Josh')
joanna = Member('Joanna')
sean = Member('Sean')
members = [josh, joanna, sean]

# Create a class and add the members to it. 
my_class = MyClass()
my_class.members = members
print my_class.name
for member in my_class.members: 
    print member.name
Data Science
Josh
Joanna
Sean
In [11]:
josh.add_question('Hellooooo?')
joanna.add_answer('???????')

print my_class.num_questions_asked()
print my_class.num_questions_answered()
1
1

Want some practice?

Have a look at the intro_classes_practice.ipynb notebook!

 Check out these related articles


5 More Tools Data Scientists Need to Know

 



What’s the Difference Between Data Engineering and Data Science?

 



Common Data Science Interview Questions

 


Back to Full List

Want to learn more?

Galvanize offers an 6-Week part time workshop, as well as a 12-week full-time program in Data Science that teaches you how to make an impact as a contributing member of a data analytics team.

Learn About our Immersive Programs Register for a Workshop

Sign up to get updates direct to your inbox