promoting [] by superclass?
Terry Reedy
tjreedy at udel.edu
Wed Jun 9 06:47:31 EDT 2004
"Jim Newton" <jimka at rdrop.com> wrote in message
news:2imqj3Fopq78U1 at uni-berlin.de...
> So it would be great if Pair(1,2,3,4,5) would
> return [1, [2, [3, [5, nil]]]] with all the bracketed
> lists promoted to class Pair. Can that be done
> with the __init__ function? currently i'm doing that
> with a seperate function which takes any sequence as its argument.
....separate...
> Basically i'd like the Pair.__init__ in the case of Pair(1,2,3,4,5),
> to set self[0]=1, and self[1] = Pair(2,3,4,5) in some iterative
> way.
If you use Pair.__init__, I believe the buildup has to be top-down
recursive. Botton-up iteration would require a factory function. See
below.
> Robert Brewer wrote:
> > TypeError saying that __init__ takes a different number of arguments.
If
> > you want to override __init__, it should be written:
> >
> >>>>class x1(list):
> >
> > ... def __init__(self, sequence):
> > ... pass
In order for Pair() to work like list(), sequence must be optional. I
default it to None since that works. While default [] works in this case,
it is not needed and is often a bug. First a small test to verify what
init gets:
>>> class Pair(list):
... def __init__(self, seq=None):
... print self, seq
...
>>> l = Pair([1,2,3])
[] [1, 2, 3]
Since list (and Pair) are mutable, new creates an empty object, which
__init__ must fill in. The parameters of __init__ are the empty object,
conventionally called 'self', and the sequence to be used to fill it in.
Now for real:
class Pair(list):
def __init__(self, seq=None):
if seq:
self.append(seq[0])
self.append(Pair(seq[1:]))
p = Pair([1,2,3])
>>>print p
[1, [2, [3, []]]]
>>> while p:
... print type(p)
... p = p[1]
...
<class '__main__.Pair'>
<class '__main__.Pair'>
<class '__main__.Pair'>
>>> p, type(p)
([], <class '__main__.Pair'>)
>>> p2=Pair([])
>>> p == p2
1
Is ths what you wanted?
Alternatively, if Pair is to be initialized with pairs, as might seem
sensible:
class Pair2(list):
def __init__(self, pair=None):
if pair:
if len(pair) == 2:
self.append(pair[0])
self.append(pair[1])
else: raise ValueError('nonempty Pair must be initialized with
pair')
then build up with iteration:
def makePair(seq): # this could be a Pair staticmethod
p = Pair2()
while seq:
p = Pair2((seq.pop(),p))
return p
>>> p2 = makePair([1,2,3])
>>> p2
[1, [2, [3, []]]]
>>> while p2: print type(p2); p2 = p2[1]
...
<class '__main__.Pair2'>
<class '__main__.Pair2'>
<class '__main__.Pair2'>
Terry J. Reedy
More information about the Python-list
mailing list