0

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?

Community
  • 1
  • 1
  • possible duplicate of [Python \_\_init\_\_ and self what do they do?](http://stackoverflow.com/questions/625083/python-init-and-self-what-do-they-do) – Martijn Pieters Nov 13 '12 at 11:35
  • @Martijn No, that's not a possible duplicate, as defined in the close dialog. It does not cover *exactly* the same content. Your own answer to this question, if merged in as an answer to the linked question, would not answer it in any satisfactory way, it would just look out of place and confuse readers. – Lauritz V. Thaulow Nov 13 '12 at 11:58
  • @lazyr: that's because I found the comment mentioned in my answer after the dupe vote. The other question certainly answers what `__init__` is *for* though. – Martijn Pieters Nov 13 '12 at 12:02
  • @Martijn What I'm trying to convey is that whether another question *answers* the question that OP has, and whether it is a *duplicate*, are two different considerations. A question closed as a duplicate needs to be an *exact* duplicate (the word *exact* is used twice in the closing text). In this case, *this* question asks about the difference between `init__` and `__init__`, while the *linked* question asks what `__init__` and `self` does. So even if reading the linked answer would mostly answer this question, they're definately (as in, by definition) not duplicates. – Lauritz V. Thaulow Nov 13 '12 at 12:10
  • 1
    @lazyr: In practice, you'll find that 'close enough' is reason enough to close as a dupe. Sometimes, an OP doesn't quite know what they are asking for, and another, better worded question does answer the actual question. Closing as a dupe is then more than appropriate. But we are veering wildly off-topic here, if you want to discuss the relative merits of dupe closing philosophies you should take it to [metase] instead. – Martijn Pieters Nov 13 '12 at 12:11
  • @Martijn Then it is my (strong) opinion that either the closing text should be revised to match the common practice, or the common practice should be changed to be in line with the closing text. I loathe unwritten rules and rules that are ignored by common convention. But I guess that's my problem. Thank you for clearing this up. – Lauritz V. Thaulow Nov 13 '12 at 12:17
  • Now it is a duplicate of [Subclassing Python tuple with multiple \_\_init\_\_ arguments](http://stackoverflow.com/q/1565374) instead. :-) – Martijn Pieters Nov 13 '12 at 12:21
  • it is not a duplicate of anything, since those two do not answer my question as this one does :) –  Nov 13 '12 at 12:35
  • I think if you use `__init__` you should call `super.__init__` for it to work. – Uri Aug 31 '15 at 13:06

3 Answers3

11

__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.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
3

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.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
2

__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.

btel
  • 5,563
  • 6
  • 37
  • 47