Home > Net >  Inherit Tuple in python - ordered tuple
Inherit Tuple in python - ordered tuple

Time:07-17

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