0

I made a tuple subclass to add a property to a tuple. Using same logic as with a list subclass which works without problems. Code:

class TupleObject(tuple):
    def __init__(self, property, _tuple):
        super().__init__(_tuple)
        self.property = property

_tuple = TupleObject(property, (0, 0))

Throws error:

TypeError: tuple expected at most 1 arguments, got 2

How could I make this work? Using this exact method with a list subclass works as expected.

martineau
  • 119,623
  • 25
  • 170
  • 301
Bas Velden
  • 408
  • 1
  • 7
  • 21

1 Answers1

4

Because tuples are immutable, you need to override __new__ to be able to modify the object before the instance is created.

class TupleObject(tuple):

    def __new__(cls, property, _tuple):
        self = super().__new__(cls, _tuple)
        self.property = property
        return self

_tuple = TupleObject('a prop', (0, 0))
_tuple, _tuple.property

Produces

((0, 0), 'a prop')
mfitzp
  • 15,275
  • 7
  • 50
  • 70
  • 1
    This code is broken; it will make `property` a *class* attribute of `TupleObject`, not an instance attribute, because the first argument is the class itself, not an instance to initialize. You need to receive the first argument as `cls` (to avoid confusing people), then do: `self = super().__new__(cls, _tuple)`, `self.property = property`, `return self` – ShadowRanger Feb 17 '19 at 15:53
  • @ShadowRanger thanks for that, very good point. – mfitzp Feb 17 '19 at 16:23