how to do proper subclassing?
Peter Otten
__peter__ at web.de
Wed Aug 4 04:41:46 EDT 2004
Jonas Koelker wrote:
> I'm new to this list (/me welcomes himself).
Jonas, I suggest that you post follow-ups vaguely on topic on c.l.py. That
gives you the chance for answers that I (for example) don't know about or
care to give as well as corrections or a second opinion.
[Jonas via email]
> > >>> class Perm(list):
> >
> > ... def __init__(self, n):
> > ... list.__init__(self, range(n))
> > ... def __call__(self, i, k):
> > ... self[i], self[k] = self[k], self[i]
> > ... return self
> > ...
> >
> > >>> p = Perm(5)
> > >>> p
> >
> > [0, 1, 2, 3, 4]
> >
> > >>> p(0,4)(2,4)(0,1)(2,3)(1,2)
> >
> > [1, 3, 4, 0, 2]
> >
> > >>> p[1:2]
> >
> > [3]
> >
> > >>> p[1:3]
> >
> > [3, 4]
>
> thanks, this looks about right (slaps himself on the
> forehead - "you DO know how init works!")... :]
>
> also, p(0,4)(2,4)(0,1)(2,3)(1,2) looks really neat and
> math'ish :)
>
> > Just in case you need it later, there is a special
> > method for every operator, e. g. __getitem__() for
> >obj[sliceOrIndex], __mul__() for multiplication etc.
>
> Yeah, I knew that. I might make __int__() convert the
> perm to a ranking number in linear time. See
My mentioning of special methods doesn't mean that I think they are always
the best choice. I would prefer both p.rank() and rank(p) over int(p).
> http://www.cs.uvic.ca/~ruskey/Publications/RankPerm.html
>
> .. don't worry, I can implement it myself.
Don't worry, I won't :-)
> btw, if I want to set the "list part" of the perm, how
> do I do that?
p[:] = [1, 2, 3, 4, 5]
p[:2] = p[1], p[0]
p[2] = [99]
If you want to ensure that the permutation is still valid after assignment
you have to write your own __setitem__() method.
> p = [4,0,3,2,1] would turn p into a list.
> p = perm(5)(0,4)(2,4)(0,1)(2,3)(1,2) is valid (right?)
> but time consuming.
That was just for fun... most likely faster than
while p != [4,0,3,2,1]: random.shuffle(p)
> I'd say it'd be easier/better to implement it as:
> >>> class Perm(list):
>
> ... def __init__(self, n):
> ... list.__init__(self, n)
The good news: if __init__() does nothing but call the base class'
__init__(), you need not write one at all.
> ... def __call__(self, i, k):
> ... self[i], self[k] = self[k], self[i]
> ... return self
>
> >>> p = Perm([4, 0, 3, 2, 1])
>
> ... anyways, thanks :)
You're welcome.
Peter
More information about the Python-list
mailing list