Python · object-oriented programming

Classes & Objects

A class is a blueprint; objects are the things built from it, each with its own data.

Blueprint and objects

class Dog
· name
· age
· bark()
→
Dog objectname = "Rex"
age = 3
Dog objectname = "Max"
age = 5

One class, many objects: every object has its own values for the same attributes.

Simple class


          # define class
          class Dog:
              pass
          # create object
          my_dog = Dog()
        

Calling the class like a function, Dog(), builds a new object.

Class with __init__


          # constructor
          class Dog:
              def __init__(self, name, age):
                  self.name = name
                  self.age = age
          dog = Dog("Rex", 3)
          # ans: dog.name is "Rex"
        

Dog("Rex", 3) makes an empty object, then runs __init__ with self pointing at it.

Instance attributes


          # access attributes
          class Dog:
              def __init__(self, name):
                  self.name = name
          dog = Dog("Rex")
          dog.name
          # ans: "Rex"
          dog.name = "Max"
          # ans: "Max"
        

Instance methods


          # methods
          class Dog:
              def __init__(self, name):
                  self.name = name
              def bark(self):
                  return f"{self.name} says Woof!"
          dog = Dog("Rex")
          dog.bark()
          # ans: "Rex says Woof!"
        

dog.bark() passes dog in as self automatically.

Class variables


          # class variable (shared)
          class Dog:
              species = "Canis familiaris"
              def __init__(self, name):
                  self.name = name
          Dog.species
          # ans: "Canis familiaris"
          Dog("Rex").species
          # ans: "Canis familiaris"
        

An object without its own species looks it up on its class.

Exercises

Predict the result, then press → to watch the objects.

Exercise 1


          # what is type?
          class MyClass:
              pass
          obj = MyClass()
          type(obj)
          # ans: <class 'MyClass'>
        

Exercise 2


        # __init__ return?
        class MyClass:
            def __init__(self):
                return 5
        # ans: TypeError (__init__ must return None)
      

The error appears when you create an object with MyClass(): __init__ sets up the object; it must not return anything.

Exercise 3


          # self parameter?
          class MyClass:
              def method(self):
                  return self
          obj = MyClass()
          obj.method() is obj
          # ans: True
        

Exercise 4


          # class vs instance variable?
          class MyClass:
              x = 5
          obj = MyClass()
          obj.x
          # ans: 5 (from class)
          obj.x = 10
          obj.x
          # ans: 10 (instance variable)
        

Exercise 5


          # forget self?
          class MyClass:
              def method():
                  pass
          obj = MyClass()
          obj.method()
          # ans: TypeError (missing self)
        

Python calls method(obj), but method takes no arguments.

Exercise 6


          # multiple instances?
          class Counter:
              def __init__(self):
                  self.count = 0
          c1 = Counter()
          c2 = Counter()
          c1.count = 5
          # ans: c2.count is still 0
        

Exercise 7


          # class variable modification?
          class MyClass:
              x = []
          obj1 = MyClass()
          obj2 = MyClass()
          obj1.x.append(1)
          # ans: obj2.x is [1] (same list!)
        

Exercise 8


          # attribute not found?
          class MyClass:
              pass
          obj = MyClass()
          obj.missing
          # ans: AttributeError
        

Exercise 9


          # isinstance?
          class MyClass:
              pass
          obj = MyClass()
          isinstance(obj, MyClass)
          # ans: True
        

Exercise 10


          # __dict__?
          class MyClass:
              def __init__(self):
                  self.x = 5
          obj = MyClass()
          obj.__dict__
          # ans: {'x': 5}
        

__dict__ is the object's own attributes, exactly the rows in its box.

Remember

__init__ fills in

It runs on every new object, with self set to that object, and returns nothing.

self is the object

Every method gets the object it was called on as its first parameter.

Own vs shared

self.x = … belongs to one object; a variable in the class body is shared by all.

Shared mutables

A list in the class body is one list for every object; changing it through one changes it for all.