Explain Codes LogoExplain Codes Logo

What do init and self do in Python?

python
self
init
instance-variables
Alex KataevbyAlex Kataev·Aug 7, 2024
TLDR

__init__ is the initializer method configuring new objects with starting data. self is the instance reference enabling access to the attributes and methods of the class.

Example:

class Car: def __init__(self, color): # Car assembly starts here; 'self' and 'color' are the building blocks self.color = color # 'self.color'= the paint job my_car = Car('red') # Your car is ready; color: red print(my_car.color) # Show me my car; Output: red

Remember: __init__ gets the object ready, self is the object's mirror image inside the class blueprint.

self: Python's personal pronoun

Self acts as a reference to the current object instance. It's always the first parameter in instance methods, bridging between instance variables and methods. Here's why self matters:

  • self should always be the first parameter in a method. Without it, instance attributes and methods become inaccessible within the method.
  • Treat self as a passport for an instance. It identifies instance-specific data and can be used within the method to access or modify this data.
  • Although self is not a keyword in Python, it is a widely agreed-upon convention and should be followed for clarity.

__init__: The object builder

The __init__ method is Python's version of a constructor. It builds your instance from scratch, starting the moment you create an instance. Here's why __init__ is crucial:

  • __init__ sets the initial values for an instance. You can therefore customize these values upon creation.
  • Be careful when adding extra parameters into __init__— they must be handled correctly to avoid errors, such as a TypeError.

Monty Python's guide to house-building

Script: __init__ and self in Python are like building a house:

Imagine __init__ as the **house plan** (🏡): __init__: Specifies how to build your house, with a kitchen, rooms, etc. 🏡 (Blueprint) -> [Kitchen🍳, Room🛏️, Bathroom🚽] Think of self as the **house in-progress**: self: Represents the house being built, allowing you to add furniture. 🛠️(self) -> 🏡(Your House): Add [🛋️ Sofa, 📚 Bookshelf]

TL;DR:

- __init__: 📐**Blueprint** for house - self: 🏗️ **House** under construction

A closer look at self and __init__

self in context

Instance variables are unique to each object and using self retains this uniqueness. Here's an example:

class Cat: def __init__(self, name): # Roll the dice: here comes a new cat self.name = name # This cat's name is... Fluffy = Cat("Fluffy") # Say hello to Fluffy! Boots = Cat("Boots") # And now meet Boots! print(Fluffy.name) # "Who's a good cat?" Output: Fluffy print(Boots.name) # "It's Boots!" Output: Boots

Modifying the attributes of an object after creation doesn't affect other instances, proving the uniqueness of instance variables.

Behind the scenes with __init__

Although __init__ starts the ball rolling for an instance, __new__ has already done some of the ground work beforehand:

  • __new__ requests the memory required for the new instance.
  • __init__ then sets the initial state of the instance.
  • Python splits the construction responsibilities to make it easier for you. In most cases, __new__ works behind the scenes and you won't need to think about it.

Comparing class and instance variables

It's vital to understand the differences between class and instance variables:

  • Class variables hold shared values for all instances of the class.
  • Instance variables are tied with self, so they belong to individual objects, maintaining their own unique values.

For clarity, let's bring code to the equation:

class Dog: breed = "Unknown" # Sorry, we're not sure about the breed. It's a dog for sure, though. def __init__(self, name): # Prepare for the awws, a new puppy is coming! self.name = name # Each puppy gets a name tag. No mix-ups here! Dog.breed = "Husky" # We've got it! It's a breed of Husky! Snow = Dog("Snow") # Meet Snow, the Husky. Frost = Dog("Frost") # Here's Frost, Snow's lovely sibling. print(Snow.breed) # "What breed is Snow?" Output: Husky print(Frost.name) # "Who's the good doggy?" Output: Frost

Memory tip: Class variables are communal; instance variables are individualistic.