Reputation: 839
I am reading the book Mastering Object-Oriented Python. In the part of book where it talks about the __new__
method and immutable objects, it says something like the __new__()
method is used to extend the immutable classes where the __init__()
method can't easily be overridden. It also gives an example as below
class Float_Fail(float):
def __init__(self, value, unit):
super().__init__(value)
self.unit = unit
f = Float_Fail(6.5, "knots")
TypeError Traceback (most recent call last)
<ipython-input-2-9511e6ca03be> in <module>()
----> 1 f = Float_Fail(6.5, "knots")
TypeError: float() takes at most 1 argument (2 given)
I'm just curious why float gives this error. I mean, we can initialize a float like this:
f = float(1.1)
Doesn't it mean the __init__()
method of float
class takes the number as it's second argument. If not, how is the initialization of an immutable class implemented in Python?
Upvotes: 1
Views: 978
Reputation: 251548
If you do MyClass(1)
, then 1
is indeed passed as an argument to __init__
. But __new__
is called before __init__
, so 1
is first passed as an argument to __new__
. The error you are seeing is because you didn't override __new__
, so the inherited float.__new__
is being called, and it doesn't accept your extra argument. It never gets a chance to even try calling __init__
, because it fails when trying to call __new__
.
This is explained in the documentation. As clearly stated there, the arguments you pass when instiating a class (e.g., the 1
in MyClass(1)
) are passed to both __new__
and __init__
, in that order.
Upvotes: 3
Reputation: 184345
By the time the __init__
method runs, the object already exists. Since the object is immutable, its value can't be changed in __init__
.
Upvotes: 0