What does self do in the example? And is `pipi_pitbull` an object?

I am struggling to understand the example given.

class Dog():
  dog_time_dilation = 7

  def time_explanation(self):
    print("Dogs experience {} years for every 1 human year.".format(self.dog_time_dilation))

pipi_pitbull = Dog()
pipi_pitbull.time_explanation()
# Prints "Dogs experience 7 years for every 1 human year."

Notice we didn’t pass any arguments when we called .time_explanation() , but were able to refer to self in the function body. When you call a method it automatically passes the object calling the method as the first argument

I do not understand the role of self in this instance. Does the code self.dog_time_dilation call the number seven as a class variable for dog? Is self part of the dog class?

Also, is pipi_pitbull the object calling the method?

TIA

This is an issue which has come up several times recently: how should you call a class variable?

In this specific case, self.dog_time_dilation takes the class variable 7 and prints it. The method would work the same if the expression were Dog.dog_time_dilation. It does not make any practical difference, since the number is printed, and not saved as an attribute of the calling object.

Yes, pipi_pitbull is the object calling the method.


Let’s add some methods and a new class variable:

class Dog():
    dog_time_dilation = 7
    number_of_dogs = 0
    def __init__(self):
        Dog.number_of_dogs += 1
        self.dog_time_dilation = Dog.dog_time_dilation

    def time_explanation(self):        
        print("Dogs experience {} years for every 1 human year.".format(self.dog_time_dilation))

    def change_multiplier(self, x):
        self.dog_time_dilation += x  # changes the value only for the calling object

OK, now call:


pipi_pitbull = Dog()
pipi_pitbull.time_explanation()
pipi_pitbull.change_multiplier(3)  # changes for pipi only
pipi_pitbull.time_explanation()
bobby_boxer = Dog()
bobby_boxer.time_explanation()  # original class variable
print(Dog.number_of_dogs)  # class variable changes with each new dog

Output:

Dogs experience 7 years for every 1 human year.  # 1st call for pipi
Dogs experience 10 years for every 1 human year. # 2d call for pipi
Dogs experience 7 years for every 1 human year. # 1st call for bobby
2

If you look at the above, you can see that if I call a class variable using self (as in change_multiplier() method), the change affects only the calling object (pipi). But if I change it using the class name (as in number_of_dogs), it is changed for all.


So, it depends upon what you are using the class variable for. If it is a constant, applicable for all objects, and never to be changed, I’d use ClassName.var (and probably name the variable in all caps.) If it is a sort of starter or initial value for each object, but which may change in a different way for each object, best to use self.var. And if it is a class variable offering information about the class, such as number of members, obviously use ClassName.var.