Reputation:
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
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
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
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