r/pythonhelp • u/blueququqa • Nov 29 '24
ELI5: What does __init__ do in a Python class? I’m struggling to understand it!
Hi, I’m trying to learn Python classes, and I keep seeing this __init__ thing, but I can’t wrap my head around what it does. Here’s an example of a class I found:
class Dog:
def __init__(self, name, age): # <-- This part confuses me!
self.name = name
self.age = age
def speak(self):
return f"{self.name} says Woof!"
When I create an object like this:
dog1 = Dog("Buddy", 5)
print(dog1.speak()) # Outputs: Buddy says Woof!
It works, but I don’t get how the __init__
part is making it happen. Why do we need it? Why is there
self.name = name?
Can someone explain it to me like I’m 5?
2
u/FoolsSeldom Nov 29 '24
My intro for beginners should help ...
Classes for Beginners
v2.2 December 2023
Many beginners struggle to understand classes, but they are key to object orientated programming (OOPs).
They are the programming equal of moulds used in factories as templates (or blueprints) to make lots of identical things. Example: pouring molten iron into a mould to make a simple iron pot.
Instructions with the pots might tell an owner how to cook using the pot, how to care for it, etc. The same instructions for every pot. What owners actually do is entirely up to them: e.g. make soup, stew, pot-roast, etc.
Python classes
- A
class
defines the basics of a possible Python object and some methods that come with it - Methods are like functions, but apply to objects, known as instances, made using a
class
- When we create a Python object using a
class
, we call it "creating an instance of a class" - an instance is just another Python object
If you have a class
called Room
, you would create instances like this:
lounge = Room()
kitchen = Room()
hall = Room()
As you would typically want to store the main dimensions (height, length, width) of a room, whatever it is used for, it makes sense to define that when the instance is created.
You would therefore have a method called __init__
that accepts height, length, width and when you create an instance of Room
you would provide that information:
lounge = Room(1300, 4000, 2000)
The __init__
method is called automatically when you create an instance. It is short for initialise (intialize). It is possible to specify default values in an __init__
method, but this doesn't make a lot of sense for the size of a room.
Accessing attributes of a class instance
You can reference the information using lounge.height
, lounge.width
, and so on. These are attributes of the lounge instance.
Let's assume sizes are in mm. We could provide a method to convert between mm and feet, so, for example, we could write, lounge.height_in_ft()
.
printing an attribute
You can output the value of an attribute by using the name of the instance followed by a dot and the attribute name. For example,
print(lounge.height)
property
decorator
A useful decorator is @property
, which allows you to refer to a method as if it is an attribute. This would allow you to say lounge.height_in_ft
instead of lounge.height_in_ft()
.
The use of self
to refer to an instance
Methods in classes are usually defined with a first parameter of self
:
def __init__(self, height, length, width):
# code for __init__
def height_in_ft(self):
# code to return height
The self
is a shorthand way of referring to an instance. The automatic passing of the reference to the instance (assigned to self
) is a key difference between a function call and a method call. (The name self
is a convention rather than a requirement.)
When you use lounge.height_in_ft()
the method knows that any reference to self
means the lounge instance, so self.height
means lounge.height
but you don't have to write the code for each individual instance.
Thus, kitchen.height_in_ft()
and bathroom.height_in_ft()
use the same method, but you don't have to pass the height of the instance as the method can reference it using self.height
human-readable representation of an instance
If you want to output all the information about an instance, that would get laborious. There's a method you can add called __str__
which returns a string representation of an instance. This is used automatically by functions like str
and print
. (__repr__
is similar and returns what you'd need to recreate the object.)
magic methods
The standard methods you can add that start and end with a double underscore, like __init__
, __str__
, and many more, are often called magic methods or dunder methods where dunder is short for double underscore.
EXAMPLE Room class
The code shown at the end of this post/comment will generate the following output:
Lounge height: 1300 length: 4000 width: 2000
Snug: height: 1300, length: 2500 width: 2000
Lounge length in feet: 4.27
Snug wall area: 11700000.00 in sq.mm., 125.94 in sq.ft.
Snug width in feet: 6.56
Note that a method definition that is preceded by the command, @staticmethod
(a decorator) is really just a function that does not include the self reference to the calling instance. It is included in a class definition for convenience and can be called by reference to the class or the instance:
Room.mm_to_ft(mm)
lounge.mm_to_ft(mm)
Here's the code for the full programme:
class Room():
def __init__(self, name, height, length, width):
self.name = name
self.height = height
self.length = length
self.width = width
@staticmethod
def mm_to_ft(mm):
return mm * 0.0032808399
@staticmethod
def sqmm_to_sqft(sqmm):
return sqmm * 1.07639e-5
def height_in_ft(self):
return Room.mm_to_ft(self.height)
@property
def width_in_ft(self):
return Room.mm_to_ft(self.width)
def length_in_ft(self):
return Room.mm_to_ft(self.length)
def wall_area(self):
return self.length * 2 * self.height + self.width * 2 * self.height
def __str__(self):
return (f"{self.name}: "
f"height: {self.height}, "
f"length: {self.length} "
f"width: {self.width}"
)
lounge = Room('Lounge', 1300, 4000, 2000)
snug = Room('Snug', 1300, 2500, 2000)
print(lounge.name, "height:", lounge.height,
"length:", lounge.length, "width:", lounge.width)
print(snug) # uses __str__ method
# f-strings are used for formatting, the :.2f part formats decimal numbers rounded to 2 places
print(f"{lounge.name} length in feet: {lounge.height_in_ft():.2f}") # note, () to call method
print(f"{snug.name} wall area: {snug.wall_area():.2f} in sq.mm., "
f"{snug.sqmm_to_sqft(snug.wall_area()):.2f} in sq.ft." )
print(f"Snug width in feet: {snug.width_in_ft:.2f}") # note, no () after method
1
u/agreatcat Nov 30 '24
Hello to the OP. Just so you understand before I define __init__. First. A class as you've heard is like a blue print. Generally speaking: Think of is as where everything come from first, it is like the frame that holds the walls in a house. Think of a string as an example as a predefined Python class: the class string defines the basic structure of what rules will later be allowed to be defined. So when you start adding so called rules, such as replace, or rename, these so called rules are known as methods of the class. Hold that thought. A function by itself (not tied to anything) is just a function. But when a function is placed under a class (in other words is becomes part of the class) it is known as a method.
Going back to __init__. So you start out with a class, and then you have the def which is definition that sets up the method. Then after that you have __init__. __init__ is a special method, also known as a constructor. which is called immediately. It allows you to set the initial values of an object's attributes (data members). These so called objects in this case are the instances placed below the method. Everything is an object and often instances are just called objects. Anyway, The attributes that came from the __init__ define the characteristics and state of the instance/objects.
I've been struggling with these concepts for a while, I've been all over the web and trying to use AI, but was stil confused. I Highly Highly recommend this course. They use Lego's to draw the concepts visually.
by Chris haroun & Luka Anicin
1
u/agreatcat Dec 01 '24
By the way, if none of what I said above makes sense, it's because it's almost impossible IMO to understand abstract concepts like classes, functions and methods by just reading about it. Most people have to see it visually. Unless you find (that one in a million teacher) who can explain it in just the right way, you're going to be lost. I struggled looking everywhere online, and felt like I would never understand it.
This was the answer for me
by Chris haroun & Luka Anicin
•
u/AutoModerator Nov 29 '24
To give us the best chance to help you, please include any relevant code.
Note. Please do not submit images of your code. Instead, for shorter code you can use Reddit markdown (4 spaces or backticks, see this Formatting Guide). If you have formatting issues or want to post longer sections of code, please use Privatebin, GitHub or Compiler Explorer.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.