Carlos Adir
Carlos Adir

Reputation: 472

Inherit Tuple in python - ordered tuple

I want to create a class that:

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?

Upvotes: 2

Views: 730

Answers (2)

Haksell
Haksell

Reputation: 116

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])

Upvotes: 1

Guy
Guy

Reputation: 50949

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))

Upvotes: 1

Related Questions