Why use __init__

Why do we have to use the init() constructor to initialize values? We can just initialize them without the constructor right?

Thanks,

Andrej

We cannot pass in instance variable values without the parameter list of __init__(). Any variable declared in the class belong to the class. All instances have the same values.

>>> class Foo:
    bar = 'bar'

    
>>> faz = Foo()
>>> baz = Foo()
>>> faz.bar
'bar'
>>> baz.bar
'bar'
>>> 

To make it an instance variable we need to re-assign it…

>>> faz.bar = 'foobar'
>>> faz.bar
'foobar'
>>> baz.bar
'bar'
>>> 

Ok so basically we use constructors if we want different instances to have and use different variables?

Yes. It’s what makes them unique.

>>> from math import pi

>>> class Shape:
	PI = round(pi, 4)
	def __init__(self, locus):
		self.locus = locus

		
>>> circle = Shape('circle')
>>> ellipse = Shape('ellipse')
>>> circle.locus
'circle'
>>> ellipse.locus
'ellipse'
>>> circle.PI
3.1416
>>> ellipse.PI
3.1416
>>> Shape.PI
3.1416
>>> 

But like you said you can “To make it an instance variable we need to re-assign it”. So technically you don’t need a constructor to reassign variables, but you do need them to create new ones? Or can you create new ones likes this

Class Foo:
bar = 'bar'

faz = Foo()
faz.create = 'create'

or

>>> from math import pi

>>> class Shape:
	PI = round(pi, 4)
	locus = 'start'

		
>>> circle = Shape()
>>> circle.locus = 'circle'
>>> ellipse = Shape()
>>> ellipse.locus = 'ellispe'

vs

>>> from math import pi

>>> class Shape:
	PI = round(pi, 4)
	def __init__(self, locus):
		self.locus = locus

		
>>> circle = Shape('circle')
>>> ellipse = Shape('ellipse')
>>> circle.locus
'circle'
>>> ellipse.locus
'ellipse'

That would give then attributes that none of the other instances would have.

Exactly so whats the purpose of init() if you can change and add variables to the instances without it?

You’re asking me to justify an important method of the class object. Afraid I’m more interested in how to use the language, not subvert it.

I am just confused why the init() function is necessary

When we start asking why questions we find the answers get grainy. Easier to learn the how, at first, and let the reasoning and logic reveal themselves after the mechanics are better known.

Ok cool that makes sense

1 Like

You can get by without defining an __init__ method for a class. However, classes should be designed to be convenient to initialize and use. An __init__ method can be used to make it easy to initialize instance variables easily and correctly.

Here’s a Triangle class with no __init__ method specified for it:

class Triangle:
  def set_side_a(self, length):
    self.side_a = length
  def set_side_b(self, length):
    self.side_b = length
  def set_side_c(self, length):
    self.side_c = length

t = Triangle() # Instantiate a Triangle without any sides
# Now we need to set up the sides
t.set_side_a(7) # We could use a defined method to assign a side
t.side_b = 22 # We could assign side_b directly
t.side_c = 89 # Also assign side_c directly
# Of course, Triangle t is invalid, with the length of one side
# exceeding the sum of the lengths of the two others

That wasn’t very convenient, and our Triangle instance is invalid.

Here’s an __init__ method that would make initializing the side lengths much more convenient, and that would prevent us from having the length of one side exceed the sum of the lengths of the two others:

  def __init__(self, side_a, side_b, side_c):
    # An __init__ method with validation
    self.perimeter = side_a + side_b + side_c
    if (side_a >= self.perimeter / 2 or
        side_b >= self.perimeter / 2 or
        side_c >= self.perimeter / 2):
      raise ValueError
    self.side_a = side_a
    self.side_b = side_b
    self.side_c = side_c

An __init__ method provides a convenient means of initializing values, checking their validity, and performing whatever other tasks that are needed at the time an instance of a class is created. We can do it the hard way instead, but in the long run, we would wish we had made it easier by defining an __init__ method.

2 Likes

Wow that helps a lot thanks. I also saw that a default constructor is made if you don’t provide your own constructor in a class.

Why does the renderer need to make this default constructor to make the class function properly? What’s the reason for needing a constructor for making a class function.

This might not be true for Python but for different coding languages I heard its true like Java

Thanks,

Andrej

When a class is defined, certain default methods are automatically made part of the class definition, unless the programmer redefines them. This is so that the class has some minimal functionality, by default.

An __init__ method is expected and automatically called when an instance of the class is created, so there needs to be one to call. If the programmer hasn’t created an __init__ method for the class, the default one that gets called does essentially nothing.

Let’s define a class that does nothing much and see what default methods it has.

>>> class Spam:
   pass

>>> dir(Spam)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
'__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', 
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', 
'__sizeof__', '__str__', '__subclasshook__', '__weakref__']

You can do a search on these methods, if interested. They exist so that the programmer can add functionality to a class by defining them explicitly.

Ok cool thank you. When you used dir(Spam) are you looking for attributes or methods? In one of the courses here it says dir() looks for attributes and not methods. How are attributes different from methods? Also is there any way to look at the code that goes behind these methods/attributes? Somewhere online maybe.

Also when I do print(dir(5)) it says that__add__is an attribute, but when you use __add__ do you use it without the double underscores? Or do you you always have to use dunder attributes with double underscores?

Thanks

There is little to be gained by peering too deeply under the hood, especially if we are barely rooted in the fundamentals.

  • Are methods attributes?

  • What are docstrings?

  • What are builtins?

  • What are dunder methods?

  • What is the meaning of type?

Yea I am trying to learn what those things are

One would suggest concentrate your efforts there, and complete the basic track. Be sure to do a complete review of the track, and get more practice on the rudiments. Find new ways to write your solutions, and take the time to explain to yourself the author’s and other solutions you’ve seen.

dir(5)

Under the hood, 5 is a fixed number, an int. It is from the int class that 5 inherits its attributes.

The __add__ method is used to define the action of the + operator for a type. For int, it concerns the arithmetic sum of the operands. Don’t call the dunder methods directly by name. For example, use the + operator to add numbers.

If you are defining a class and want the + operator to perform some specific operation for that class, define the __add__ method for that class.

Study the fundamentals first, as @mtf advises.

1 Like

Ok thanks your explanations help a lot. One thing I am still confused about is attributes vs methods. I am trying to find the answer online but it is proving to be a difficult task.