Python - what is self and init?

class Animal():  #simple class definition
    colour="brown" #all instances of class will be brown

bear=Animal
bear.colour



class Animal():
    colour="brown"
    #the init method is called when an instance is created
    def __init__(self, height): 
        self.height = height
    
elephant=Animal(300) #don't have to supply the self arg, just height
print(elephant.colour)
print(elephant.height)
#why use "self"?
#1. to initialize instances of the class with certain attributes
#not just attributes within the class as a whole

class Animal():
    #take colour out of here
    def __init__(self, height, colour): #add the attribute here in the init method
        self.height = height
        self.colour = colour

fish=Animal(10, "pink")
print(fish.colour)
print(fish.height)

#2. to refer to the instance in other methods

class Animal():
    def __init__(self, height, colour): #add the attribute here in the init method
        self.height = height
        self.colour = colour
    def growAnimal(self, amount):
        self.height += amount

crow=Animal(20, "black")
print(crow.height)
crow.growAnimal(10)
print(crow.height)