Learning classes

Hey there!

I’m just learning about what’s the difference between class and object and how to create classes but I got stucked in this (I took the code from Zed in another topic):

class Truck(object):
def __init__(self, color):
    self.color = color

In line 3. Why we have to create that variable “self.color = color”? I don’t fully understand that point and it’s getting me blocked and I cannot move forward in the book.

Thank you so much to everyone who’ll spend a few moments answering this beginner question.

Try this similar thread and see if it helps at all.

1 Like

Alright, so this is a common problem and the easiest way to explain this is to ask you question like this:

“What’s the difference between A Dog and my dog MrSnuggles?”

That question should be confusing you because “a dog” is a generic term for all the dogs possible, so MrSnuggles IS a dog, which means there is no difference. They’re the same thing, just using a different term for each with different views.

The same thing applies to “what’s the difference between a class and object”. The object IS the class, there is no difference. There IS a difference between two different objects of the same class, but the class is what defines the object so no difference.

In this case Dog is the class, and mr_snuggles is the object:

class Dog(object):
    ___init__(self, name):
        self.name = name

mr_snuggles = Dog("MrSnuggles")

Now, here’s the reason for the self: You want to be able to write a definition for the class Dog, that works for every possible dog you could make. If you have fluffy, mr_snuggles, and tripod as dogs like this:

fluffy = Dog("Fluffy")
mr_snuggles = Dog("MrSnuggles")
tripod = Dog("Tripod")

Then when the __init__, how does this function know which one you are talking about? If you wanted to set the name for each of these, you’d need to know which one you’re setting an the name for right? You couldn’t do this:

class Dog(object):
    ___init__(name):
        mr_snuggles.name = name

You can’t do that for two reasons:

  1. The variable mr_snuggles doesn’t exist yet. You’re in the __init__ method which is run before the Dog object is assigned to mr_snuggles. That means you can’t refer to it here yet.
  2. So then what happens when you try to create fluffy and tripod? You’d need a Dog class for every possible variable you’re going to make that’s a dog just to anticipate the variables used.

So, the solution Python uses is to give you a generic variable named self and it’s the first parameter. Then you just use self and it means “the current object”.

code]
class Dog(object):
_init(self, name):
self.name = name

fluffy = Dog(“Fluffy”)
mr_snuggles = Dog(“MrSnuggles”)
tripod = Dog(“Tripod”)
[/code]

Now, when fluffy is created, self inside __init__ is the object for fluffy. And when you make mr_snuggles self becomes the object for mr_snuggles. And when you make tripod self becomes the object for tripod.

That’s it. I think people over think this too much but all self means is “the current object”.

2 Likes

Hi @zedshaw!

Thank you so much, this is clarifying a lot of the mess I had in my head about object and classes. However, even though I understood the purpose of self, I don’t full understand why you delcare the parameters(?) inside init not self but, in this case, name and, in addition, why you set self.name. How can I set this name variable in each instance of the class? How does self.name = name work?

Again, thank you so much for your time. I think I’m almost there with classes and objects but there’s something I don’t get at this moment.

Hi @Ricard I will try to help, because I had trouble with this concept to.
What helped was to understand that I have to look at the objects with the same eyes I look on functions.

You can have a function like this:

def foo():
    example = 5
    return example

And you call it like this:

foo()

It alway will return 5.

But you can have a function like this:

def bar(value):
    example = value
    return example

You will call it like this:

bar(6)
bar(2)
bar(4)

And it will allways return the value you passed to it as an argument. Example:

>>> 6
>>> 2
>>> 4

With classes it is similar.

You can have a class like this:

class MyStaticPet(object):

    def __init__(self):
        self.name = "MrSnuggles"

    def print_pet_name(self):
        print(self.name

You can define a instance of this class like this:

pet = MyStaticPet()

And call the function of this instance like this:

pet.print_pet_name()

The output will always be this:

>>> MrSnuggles

But you can have code like this:

class MyDynamicPet(object):

    def __init__(self, name):
        self.name = name

    def print_pet_name(self):
        print(self.name)

You can define a instance of this class like this:

pet_one = MyDynamicPet("Fluffy")
pet_two = MyDynamicPet("Goldy")

And call the function of this instance like this:

pet_one.print_pet_name()
pet_two.print_pet_name()

The output will be this:

>>> Fluffy
>>> Goldy

So, when you say self.name = name you say: take the input that is given to this parameter above in the parenthesis of the __init__ function and assign it to the variable self.name.

The __init__ function ist the constructor of a Python-Class and initializes the new instance with the values you pass to it through the parameter in the __init__(self, my_constructor_parameter). Everything you pass there will be the value or ‘character’ of the new instance. In the example above the value of the instance pet_one is the string/name Fluffy.

I have created for my self a mnemonic that helped me to understand the concept. I always say: Whats in it? And then will look at the parameter of __init__(self, i_am_in_it) to see what the class takes.

Hope that helps a bit.
Kind regards,
Didier

1 Like

Whoa!

Didier, that was what I was looking. You are right, I was stucked with the same concepts. Now I can see this similarities with functions.

So, if I understood it right self is the instance of a class and the next parameters like name, this, that are what you declare inside the parenthesis like this:

class MyClass(object):
              def __init__(self, x, y,  z):
                     self.x = x
                     self.y = y
                     self.z = z

instance = MyClass('x', 'y', 'z')

Is that the point? In init parameters I could put both x or name.

Thank you @DidierCH!

Hi @Ricard Glad that I could help.
I would not say that self is the instance, it’s just like a signpost to the instance. As Zed said somewhere: “Inside the functions in a class, self is a variable for the instance/object being accessed.” It points to the instance and helps to avoid ambiguity, so that python knows witch variable to access, namely the one of the instance you call.

And yes you could also write, your class like this:

class MyClass(object):
              def __init__(self, name, y,  z):
                     self.x = name
                     self.y = y
                     self.z = z

instance = MyClass("fluffy", "my", "dog")

print(instance.x)
print(instance.y)
print(instance.z)

And you will get the output:

>>>fluffy
>>>my
>>>dog

But I think it’s better readable to use the same name for the parameter and the variable.

1 Like

Hey @Ricard, glad you’re getting it. Remember I had said that Classes and Modules are very similar. So, if you go back to the exercise where I have modules with functions that you call, and then a class with the same functions and use it, then you’ll see this. If you are going to a class and thinking it’s totally different, then remember I had said it’s similar to a module. Not exactly the same, but similar.

So if you made a module:

# pets.py

def init(name):
    return {'name': name}

You could make a pet with this module like this:

import pets

my_snuggles = pet.init("MrSnuggles")

An object does nearly the same thing, but you don’t really need to import:

class Pet:
    def __init__(self, name):
        self.name = name

mr_snuggles = Pet("MrSnuggles")

That last line is kind of like the pet.init("MrSnuggles") from a module. In fact, when you call the class version of it, Python kind of translates it to Pet.__init__(self, "MrSnuggles"). And then self gets returned implicitly.

2 Likes

Whoa!

You guys are awesome. I love the way people here is spending time showing the basics of programming to beginners like me. I now fully understand the concepts behind class, object,… I can move forward.

Thank you so much @DidierCH, @zedshaw and @gpkesley. I’m getting more and more interested in programming each day.

1 Like

Hello @Ricard, that’s great! Keep going.