In Python 3.4, I'd like to create a subclass of float
-- something that can be used in math and boolean operations like a float
, but has other custom functionality and can receive an argument at initialization that controls that functionality. (Specifically, I wanted to have a custom __str__
and a parameter that is used in that method.)
However, I can't seem to get a subclass of float
to have a functional two-argument constructor. Why? Is this simply a limitation on extending built-in types?
Example:
class Foo(float):
def __init__(self, value, extra):
super().__init__(value)
self.extra = extra
Now if I try Foo(1,2)
I get:
TypeError: float() takes at most 1 argument (2 given)
Surprisingly, my new __init__
's arguments are enforced too, so if I do Foo(1)
I get:
TypeError: __init__() missing 1 required positional argument: 'extra'
What's the deal here? I've done similar things with subtypes of list
and was surprised it didn't work on float
.
As float is immutable you have to overwrite __new__
as well. The following should do what you want:
class Foo(float):
def __new__(self, value, extra):
return float.__new__(self, value)
def __init__(self, value, extra):
float.__init__(value)
self.extra = extra
foo = Foo(1,2)
print(str(foo))
1.0
print(str(foo.extra))
2
See also Sub-classing float type in Python, fails to catch exception in __init__()