Classes

  • class

    • attributes

    • methods

  • instances

    • __init__

  • objects

Objects Review

  • Objects are a way to combine associated data (attributes) and procedures (methods) to do upon that data with a systematic organization

  • So how do we define objects?

    • people have built & defined objects (i.e. dates and datetime)

    • defining your own

Classes

Classes define objects. The class keyword opens a code block for instructions on how to create objects of a particular type.

Think of classes as the blueprint for creating and defining objects and their properties (methods, attributes, etc.). They keep related things together and organized.

Example Class: Dog

# Define a class with `class`. 
# By convention, class definitions use CapWords (Pascal)
class Dog():
    
    # Class attributes for objects of type Dog
    sound = 'Woof'
    
    # Class methods for objects of type Dog
    def speak(self):
        print(self.sound)

A reminder:

  • attributes maintain the object’s state; they lookup information about an object

  • methods alter the object’s state; they run a function on an object

class notes:

  • classes tend to use CapWords convention (Pascal Case)

    • instead of snake_case (functions and variable names)

  • () after Dog indicate that this is callable

    • like functions, Classes must be executed before they take effect

  • can define attributes & methods within class

  • self is a special parameter for use by an object

    • refers to the thing (object) itself

  • like functions, a new namespace is created within a Class

# Initialize a dog object
george = Dog()
# george, has 'sound' attribute(s) from Dog()
print(george.sound)
Woof
# george, has 'Dog' method(s)
# remember we used `self`
george.speak()
Woof

Clicker Question #1

Which of the following statements is true about the example we’ve been using?

class Dog():
    
    sound = 'Woof'
    
    def speak(self):
        print(self.sound)
  • A) Dog is a Class, sound is an attribute, and speak is a method.

  • B) Dog is a function, sound is an attribute, and speak is a method.

  • C) Dog is a Class, sound is a method, and speak is an attribute.

  • D) Dog is a function, sound is an method, and speak is an attribute.

Using our Dog Objects

# Initialize a group of dogs
pack_of_dogs = [Dog(), Dog(), Dog(), Dog()]
# take a look at this
pack_of_dogs
[<__main__.Dog at 0x10d9b2b38>,
 <__main__.Dog at 0x10d9b2b70>,
 <__main__.Dog at 0x10d9b2ba8>,
 <__main__.Dog at 0x10d9b2be0>]
# take a look at this
type(pack_of_dogs[0])
__main__.Dog
for dog in pack_of_dogs:
    dog.speak()
Woof
Woof
Woof
Woof

Instances & self

An instance is particular instantiation of a class object. self refers to the current instance.
# Initialize a dog object
george = Dog()

From our example above:

  • Dog is the Class we created

  • george was an instance of that class

  • self just refers to whatever the current instance is

Clicker Question #2

How many instances of Dog() are created below and how many times does the speak() method execute?

pack_of_dogs = [Dog(), Dog(), Dog(), Dog()]

counter = 1

for doggie in pack_of_dogs:
    if counter <= 2:
        doggie.speak()
        counter += 1
    else:
        break
Woof
Woof
  • A) 2 instances, 2 method executions

  • B) 2 instances, 4 method executions

  • C) 4 instances, 2 method executions

  • D) 4 instances, 4 method executions

  • E) ¯\_(ツ)_/¯

Instance Attributes

An instance attribute specific to the instance we’re on.

# Initialize a group of dogs
pack_of_dogs = [Dog(), Dog(), Dog(), Dog()]
for dog in pack_of_dogs:
    dog.speak()
Woof
Woof
Woof
Woof

Clicker Question #3

Considering the output above, how many instances of dog are there?

  • A) 0

  • B) 1

  • C) 2

  • D) 3

  • E) 4

Instance attributes are attributes that we can make be different for each instance of a class. __init__ is a special method used to define instance attributes.

Example Class: Dog Revisited

  • Two trailing underscores is used to indicate something Python recognizes and knows what to do every time it sees it.

  • Here, we use __init__ to execute the code within it every time you initialize an object.

class Dog():
    
    # Class attributes for Dogs
    sound = 'Woof'
    
    # Initializer, allows us to specify instance-specific attributes
    # leading and trailing double underscores indicates that this is special to Python
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        print(self.sound)
# Initialize a dog
# what goes in the parentheses is defined in the __init__
gary = Dog(name = 'Gary') 
# Check gary's attributes
print(gary.sound)    # This is an class attribute
print(gary.name)     # This is a instance attribute
Woof
Gary
# Check gary's methods
gary.speak()
Woof

Clicker Question #4

Edit the code we’ve been using for the Class Dog to include information about the breed of the Class Dog?

# EDIT CODE HERE
class Dog():
    
    # Class attributes for Dogs
    sound = 'Woof'
    
    # Initializer, allows us to specificy instance specific attributes
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
    
    def speak(self):
        print(self.sound)
## We'll execute here
lexi = Dog(name='Lexi', breed='Italian Greyhound')
lexi.breed
'Italian Greyhound'
  • A) I did it!

  • B) I think I did it!

  • C) So lost. -_-

Class example: Cat

# Define a class 'Cat'
class Cat():
    
    sound = "Meow"
    
    def __init__(self, name):
        self.name = name
    
    def speak(self):
        print(self.sound)

Instances Examples

# Define some instances of our objects
pets = [Cat('Jaspurr'), Dog('Barkley', 'Corgi'), 
        Cat('Picatso'), Dog('Ruffius', 'Italian Greyhound')]
for pet in pets:
    print(pet.name, ' says:')
    pet.speak()
Jaspurr  says:
Meow
Barkley  says:
Woof
Picatso  says:
Meow
Ruffius  says:
Woof

Clicker Question #5

What will the following code snippet print out?

class MyClass():
    
    def __init__(self, name, email, score):
        self.name = name
        self.email = email
        self.score = score
    
    def check_score(self):        
        if self.score <= 65:
            return self.email
        else:
            return None
student = MyClass('Rob', 'rob@python.com', 62)
student.check_score()
'rob@python.com'
  • A) True

  • B) ‘Rob’

  • C) False

  • D) ‘rob@python.com’

  • E) None

UPDATE WORDING TO MAKE MORE CLEAR

Clicker Question #6

Which is the best description of objects, classes and instances?

  • A) objects are defined by instance, with particular instantiations of them called classes.

  • B) instances are defined by class, with particular instantiations of them called objects.

  • C) classes are defined by object, with particular instantiations of them called instances.

  • D) objects are defined by class, with particular instantiations of them called instances.

  • E) None of this makes any sense.

from datetime import date
## see underlying code for date class
## we know what even more of this means now!
date??

Class Inheritance

Objects can also be built from other objects, inheriting their properties and building off them.

If you have a hierarchical structure, this can be very helpful.

For our Dog() and Cat() example, you may on some more general Animal() class.

You would want Animal() to inherit all the ‘stuff’ from the other classes.

class Tool():
    
    def __init__(self):       
        self.is_tool = True
        self.tool_type = None
    
    def use_tool(self):
        print('Using tool.')

class Hammer(Tool): #inherit Tool class
    
    def __init__(self):        
        super().__init__() # inherit initialization from Tool()
        self.tool_type = 'Hammer'
        self.why = 'To hammer things.'
my_tool = Tool()
my_hammer = Hammer()
print(my_hammer.is_tool)
print(my_hammer.why)
my_hammer.use_tool()
True
To hammer things.
Using tool.

Clicker Question #7

Given the following set of classes:

class Brain(): 
    
    def __init__(self, size = None, folded = None):
        self.size = size
        self.folded = folded
        
    def print_info(self):
        folded_string = ''
        if not self.folded:
            folded_string = 'not'
        print('This brain is ' + self.size + ' and is ' + folded_string + ' folded.')
         
class SheepBrain(Brain):
    
    def __init__(self, size = 'medium', folded = False):
        super().__init__(size, folded)

What will the following print out?

sheep = SheepBrain()
sheep.print_info()
This brain is medium and is not folded.
  • A) This brain is medium and folded.

  • B) This brain is large and folded.

  • C) This brain is medium and not folded.

  • D) This brain is medium and False.

  • E) ¯\_(ツ)_/¯

Clicker Question #8

Given the following set of classes:

class Brain(): 
        
    def __init__(self, size=None, folded=None):
        self.size = size
        self.folded = folded
        
    def print_info(self):
        folded_string = ''
        if not self.folded:
            folded_string = 'not'
        print('This brain is ' + self.size + ' and is ' + folded_string + ' folded.')
        
class SheepBrain(Brain):
    
    def __init__(self, size = 'medium', folded = False):
        super().__init__(size, folded)
        
class HumanBrain(Brain):
    def __init__(self, size = 'large', folded = True):
        super().__init__(size, folded)

What will the following print out?

sheep = SheepBrain()
human = HumanBrain()
human.folded and sheep.folded
False
  • A) True

  • B) False

  • C) None

  • D) AssertionError

  • E) ¯\_(ツ)_/¯

# has access to Brain() methods
sheep.print_info()
This brain is medium and is not folded.

Classes Review

  • class creates a new class type

    • names tend to use CapWords case

    • can have attributes (including instance attributes) and methods

      • obj.attribute accesses data stored in attribute

      • obj.method() carries out code defined within method

  • instance attributes defined with __init__

    • __init__ is a reserved method in Python

    • This “binds the attributes with the given arguments”

    • self refers to current instance

  • to create an object (instance) of a specified class type (ClassType):

    • object_name = ClassType(input1, input2)

    • self is not given an input when creating an object of a specified class

Everything in Python is an Object!

Data variables are objects

print(isinstance(True, object))
print(isinstance(1, object))
print(isinstance('word', object))
print(isinstance(None, object))

a = 3
print(isinstance(a, object))
True
True
True
True
True

Functions are objects

print(isinstance(sum, object))
print(isinstance(max, object))
True
True
# Custom function are also objects
def my_function():
    print('yay Python!')
    
isinstance(my_function, object)
True

Class definitions & instances are objects

class MyClass():
    def __init__(self):
        self.data = 13

my_instance = MyClass()

print(isinstance(MyClass, object))
print(isinstance(my_instance, object))
True
True

Object-Oriented Programming

Object-oriented programming (OOP) is a programming paradigm in which code is organized around objects. Python is an OOP programming langauge.