Problem subclassing tuple
Bengt Richter
bokr at oz.net
Tue Apr 29 17:07:15 EDT 2003
On Tue, 29 Apr 2003 12:48:48 -0400, "Terry Reedy" <tjreedy at udel.edu> wrote:
>
>"John Wilson" <tug at wilson.co.uk> wrote in message
>news:mailman.1051631814.18940.python-list at python.org...
>> Given this class:
>>
>> class Holder(tuple):
>> def __init__(self, *values):
>> tuple.__init__(self, values)
>>
>>
>> When I try to create an instance:
>>
>> Holder(1, 2)
>>
>> I get:
>>
>> TypeError: tuple() takes at most 1 argument (2 given)
>>
>> It looks like the constructor for the superclass is being called
>rather than
>> the __init__ method on Holder.
>>
>> I'm obviously missing something here. Do I have to supply a __new__
>method?
>> Any help would be appreciated.
>
>
>Because tuples are immutable, one cannot mutate them in an init
>method, even to set the initial values. So, as you apparently
>suspected, they are initialized in the __new__ method from a sequence.
>This is the source of the exception (see below). tuple.__init__ should
>be a no op.
>
>>>> class Holder(tuple):
>... def __init__(self, *values):
>... print "Holder init entered"
>...
>>>> Holder(1,2)
>Traceback (most recent call last):
> File "<stdin>", line 1, in ?
>TypeError: tuple() takes at most 1 argument (2 given)
># init not entered
>>>> Holder((1,2))
>Holder init entered
>(1, 2)
>
>While Holder.__init__() cannot modify the value of self, it *can* add
>attributes (which surprised me a bit) so it can have a use.
>
>>>> class Holder(tuple):
>... def __init__(self, seq):
>... self.y = 1
>...
>>>> a=Holder((1,2))
>>>> a.y
>1
>
>I don't know what more you could do in a __new__ method.
>
I suppose you could mess with the value, e.g.,
>>> class H(tuple):
... def __new__(cls, seq):
... return tuple.__new__(cls,seq+seq)
...
>>> H([1,2,3])
(1, 2, 3, 1, 2, 3)
>>> H('abc')
('a', 'b', 'c', 'a', 'b', 'c')
>>> h= H('abc')
>>> h
('a', 'b', 'c', 'a', 'b', 'c')
>>> type(h)
<class '__main__.H'>
Regards,
Bengt Richter
More information about the Python-list
mailing list