user1329187
user1329187

Reputation:

What is the difference between init__ and __init__ in python class?

Some things do not work if I use __init__ instead of init__ in a class. I am just curious what the difference between these two is.

Here is a piece of the class. But it really does not matter because it works with init__ and it doesn't with __init__. I understand that it was a typing error, then it means that I can actually call it any way.

class Point(namedtuple('Point', 'x, y, z')):
  'class of a point as a tuple array'
  __slots__ = () # prevent creation of instance dictionaries to save memory

  def init__(self, x, y, z):
    self.x = x
    self.y = y
    self.z = z

  def __del__(self):
    'delete the Point'

  def __repr__(self):
    'Return a nicely formatted representation string'
    return '[%r, %r, %r]' % (self)

  def __str__(self):
    'printing format'
    return '%s[%r, %r, %r]' % (self.__class__.__name__,
                               self.x, self.y, self.z)

  def __add__(self, other):
    return Point(self.x + other.x, self.y + other.y, self.z + other.z)

  def __sub__(self, other):
    return Point(self.x - other.x, self.y - other.y, self.z - other.z)

  def __mul__(self, scal):
    'multiplication ny scalar'
    return Point(self.x * scal, self.y * scal, self.z * scal)

  def __div__(self, scal):
    'division ny scalar'
    if scal != 0.0:
        return Point(self.x / scal, self.y / scal, self.z / scal)
    else:
        sys.exit('Division by zero!')

My question there was "How to instantiate an object in two different ways?" and this way it works perfectly.

How to explain this?

Upvotes: 1

Views: 6941

Answers (3)

Martijn Pieters
Martijn Pieters

Reputation: 1121316

__init__ is the hook used to initialize your instance. (it is always called when you create an instance).

init__ is just a class method with a wonky name.

You need to show us your code; if something is broken when you have a method named __init__ you made a mistake there. Renaming it to init__ just means it won't be called automatically, thus not triggering your coding mistake.

In the comment you refer to, the author did use __init__ in his comment but forgot to escape the leading underscores, and they were interpreted as code to start bold text instead:

__this is bold__

becomes this is bold. Note that the trailing __ on __main__ also is lost in that comment.

In your updated code, you are trying to override the __init__ method of a (subclass) of tuple, which is a special case. By renaming the __init__ method to init__ you created a different method and did not run into this common problem at all.

See Subclassing Python tuple with multiple __init__ arguments for more detail on why this is a problem; you have to create a __new__ method instead. __new__ is the factory method to create instances, __init__ then initializes the data. But that doesn't work on immutable types such as namedtuple or tuple, since you are not supposed to change the instance after the factory created it.

In this specific case, you do not need an __init__ or a __new__ method at all because the namedtuple subclass Point already takes care of the initialization of the x, y and z attributes. By renaming __init__ to init__ you made things work, but you do end up with a pointless init__ method that you'll never use. Just delete it.

Upvotes: 11

Daniel Roseman
Daniel Roseman

Reputation: 599480

init__ has no special meaning in Python. It's just a method.

__init__ is the magic method that's called automatically on object instantiation.

If init__ works but __init__ doesn't, then something is broken in your code - probably in that method, because if it's called init__ it's almost certainly never getting called at all.

Upvotes: 3

btel
btel

Reputation: 5693

__init__ is a special method which is always called when a new object of the class is created. It should be only overloaded when you want to define additional attributes or somehow change the behaviour of your object.

Upvotes: 2

Related Questions