I want to create a class that:
- Has the same behavior as a
tuple:- Immutable elements
- Has methods
__len__,index,__getitem__and so on
- The tuple has only
floatsand it’s ordered - Has a property
qtminthat counts how many elements are equal to the minimal
So, my idea is to inherit from tuple‘s class.
class MyTuple(tuple):
@staticmethod
def VerifyIsOrdered(U: tuple[float]):
n = len(U)
for i in range(n-1):
if U[i] > U[i+1]:
raise ValueError("U must be ordered")
def __init__(self, U: tuple[float]):
MyTuple.VerifyIsOrdered(U)
super().__init__(U)
@property
def qtmin(self):
minU = min(self)
for i in range(len(self)):
if self[i] != minU:
return i
MyTuple([0, 1, 2, 3]) # qtmin = 1
MyTuple([0, 0, 0, 1, 2, 3]) # qtmin = 3
But I receive the error below at the line super().__init__(U)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
But I don’t get what’s the problem, cause when I call super it’s meant to initialize the original tuple. How can I solve it?
>Solution :
tuple is immutable, so you need to use __new__ instead of __init__. From the docs
new() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also
commonly overridden in custom metaclasses in order to customize class
creation.
def __new__(cls, U: tuple[float]):
MyTuple.VerifyIsOrdered(U)
return super(MyTuple, cls).__new__(cls, tuple(U))