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
floats
and it's ordered - Has a property
qtmin
that 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?
CodePudding user response:
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))
CodePudding user response:
for better syntax, you can use unpacking like this:
def __new__(cls,*U):
MyTuple.VerifyIsOrdered(U)
return super(MyTuple,cls).__new__(cls,U)
so you can write:
MyTuple(0, 1, 2, 3)
instead of
MyTuple([0, 1, 2, 3])