Let's say you wanted to design a useful little machine called a widget, and start producing them in a range of colours. First thing you'd do is design a blueprint. In python, writing a class is much like writing a blueprint for something. Let's write our widget!
class Widget:
pass
Well. That was easy. We could start producing these widgets right away if we liked.
first_edition_widget = Widget()
second_edition_widget = Widget()
third_edition_widget = Widget()
Nice! We have our widgets. Each widget is an instance of
class Widget:
def __init__(self, colour):
self.colour = colour
red_widget = Widget('red')
So, generally speaking, if you're reading this you should know that our
How about we add a
class Widget:
def __init__(self, colour):
self.colour = colour
def what_colour(self):
print(f"I'm a {self.colour} widget :)")
>>> red_widget = Widget('red')
>>> blue_widget = Widget('blue')
>>> red_widget.what_colour()
"I'm a red widget :)"
>>> blue_widget.what_colour()
"I'm a blue widget :)"
Here we can see that an instance of a widget is able to refer to parts of its self, using self. When a widget looks up
What is the
This more than anything, is a formality. A language design choice. A method needs to know which instance of a class it's dealing with, and passing the actual instance to it is the most explicit way of doing this. Python will automatically pass self for us, but not receive it for us. This allows us to have things like
To reiterate, how come we do
class Widget:
def __init__(self, colour):
self.colour = colour
def what_colour(self, pretend_self):
print(f"I'm a {pretend_self.colour} widget :)")
>>> red_widget = Widget('red')
>>> red_widget.what_colour(red_widget)
"I'm a red widget :)"
This time, we never used self at all! self was passed as the first argument to
If you're very clever, having been told that an instance's method needs to be passed its self as an instance you're wondering why. Why can it just *know*? Well, when you call a method on an instance, behind the scenes python is really calling the instance's class' method and passing the instance. Look at this:
class Widget:
def __init__(self, colour):
self.colour = colour
def what_colour(self):
print(f"I'm a {self.colour} widget :)")
>>> red_widget = Widget('red')
>>> Widget.what_colour(red_widget)
"I'm a red widget :)"
^^ that is why when defining a class, the methods must accept an instance!