Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old July 18th, 2005, 10:56 PM
Jane Austine
Guest
 
Posts: n/a
Default Style guide for subclassing built-in types?

Please see the following code:
--------------------------------
class rev_wrap(object):
def __init__(self,l):
self.l=l
def __getitem__(self,i):
return self.l[-i-1]

class rev_subclass(list):
def __getitem__(self,i):
return list.__getitem__(self,-i-1)

if __name__=='__main__':
l=rev_wrap([1,2,3])
assert l[0]==3
assert list(l)==[3,2,1]

l=rev_subclass([1,2,3])
assert l[0]==3
assert list(l)==[3,2,1]

I know there is "reversed" and "reverse" but that's not the point. The
code fails at the last line.

Now that UserList is deprecated(not recommended) I suppose subclassing
built-in types are preferable than wrapping them. How do I properly
change the behaviours of built-in types? I think I have to override
__iter__ and next to pass the last line. Is it a good style? If so,
what is the most recommended way of implementing them?

Thank you in advance.

Jane
  #2  
Old July 18th, 2005, 10:56 PM
janeaustine50@hotmail.com
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

Jane Austine wrote:[color=blue]
> Please see the following code:
> --------------------------------
> class rev_wrap(object):
> def __init__(self,l):
> self.l=l
> def __getitem__(self,i):
> return self.l[-i-1]
>
> class rev_subclass(list):
> def __getitem__(self,i):
> return list.__getitem__(self,-i-1)
>
> if __name__=='__main__':
> l=rev_wrap([1,2,3])
> assert l[0]==3
> assert list(l)==[3,2,1]
>
> l=rev_subclass([1,2,3])
> assert l[0]==3
> assert list(l)==[3,2,1][/color]

Oh... I forgot one. assert l==[3,2,1] at this point doesn't pass
either. "print l" outputs the wrong one([1,2,3]) as well.

  #3  
Old July 18th, 2005, 10:56 PM
Fuzzyman
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

I guess print is using the __repr__ (or __str__ ?) methods of lsit -
which you will need to override as well.

Regards,

Fuzzy
http://www.voidspace.org.uk/python/index.shtml

  #4  
Old July 18th, 2005, 10:56 PM
janeaustine50@hotmail.com
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

Fuzzyman wrote:[color=blue]
> I guess print is using the __repr__ (or __str__ ?) methods of lsit -
> which you will need to override as well.
>
> Regards,
>
> Fuzzy
> http://www.voidspace.org.uk/python/index.shtml[/color]

Thank you but the problem is that I have to express my intention in
duplicate places -- __iter__(along with "next"), __str__, __eq__ and so
on.

p.s. the reason I'm not sticking to reversed or even reverse : suppose
the size of the list is huge.

  #5  
Old July 18th, 2005, 10:56 PM
Nick Coghlan
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

janeaustine50@hotmail.com wrote:[color=blue]
> p.s. the reason I'm not sticking to reversed or even reverse : suppose
> the size of the list is huge.[/color]

Reversed is an iterator - it does NOT copy the list. In other words, reversed
already does pretty much what you want.

Cheers,
Nick.

--
Nick Coghlan | ncoghlan@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
  #6  
Old July 18th, 2005, 10:56 PM
Fuzzyman
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?


janeaustine50@hotmail.com wrote:[color=blue]
> Fuzzyman wrote:[color=green]
> > I guess print is using the __repr__ (or __str__ ?) methods of lsit[/color][/color]
-[color=blue][color=green]
> > which you will need to override as well.
> >
> > Regards,
> >
> > Fuzzy
> > http://www.voidspace.org.uk/python/index.shtml[/color]
>
> Thank you but the problem is that I have to express my intention in
> duplicate places -- __iter__(along with "next"), __str__, __eq__ and[/color]
so[color=blue]
> on.
>[/color]

If you are sublassing the built in types I guess you will have to
change all methods that have changed..

an alternative wuld be to not subclass object and override __getattr__
:

class rev_wrap:
def __init__(self,l):
self.l=l
def __getitem__(self,i):
return self.l[-i-1]
def __getattr__(self, attr):
return getattr(self.l, attr)

Regards,

Fuzzy
http://www.voidspace.org.uk/python/index.shtml
[color=blue]
> p.s. the reason I'm not sticking to reversed or even reverse :[/color]
suppose[color=blue]
> the size of the list is huge.[/color]

  #7  
Old July 18th, 2005, 10:56 PM
Kent Johnson
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

janeaustine50@hotmail.com wrote:[color=blue]
> p.s. the reason I'm not sticking to reversed or even reverse : suppose
> the size of the list is huge.[/color]

reversed() returns an iterator so list size shouldn't be an issue.

What problem are you actually trying to solve?

Kent
[color=blue]
>[/color]
  #8  
Old July 18th, 2005, 10:56 PM
janeaustine50@hotmail.com
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?


Kent Johnson wrote:[color=blue]
> janeaustine50@hotmail.com wrote:[color=green]
> > p.s. the reason I'm not sticking to reversed or even reverse :[/color][/color]
suppose[color=blue][color=green]
> > the size of the list is huge.[/color]
>
> reversed() returns an iterator so list size shouldn't be an issue.
>
> What problem are you actually trying to solve?
>
> Kent
>[/color]

Oh, you are right.

Actually, it's more complicated than simple reversion. The list order
should be somewhat "twisted" and the list is big.

For example,

[1,2,3,4,5,6,7,8,9,10]

--> [10,9,8,7,6,1,2,3,4,5]

so __getitem__(self,i) => __getitem__(self,-i-1) if i<len(size)/2,
otherwise __getitem__(self,i-len(size)/2)

I'd like to have TwistedList class that takes in an original list and
pretends as if it is twisted actually. However, I have to have
duplicate codes here and there to make it act like a "list", say assert
twisted_list == [10,9,...] and for each in twisted_list and etc.

  #9  
Old July 18th, 2005, 10:57 PM
Michael Spencer
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

janeaustine50@hotmail.com wrote:[color=blue]
> Kent Johnson wrote:
>[color=green]
>>janeaustine50@hotmail.com wrote:
>>[color=darkred]
>>>p.s. the reason I'm not sticking to reversed or even reverse :[/color][/color]
>
> suppose
>[color=green][color=darkred]
>>>the size of the list is huge.[/color]
>>
>>reversed() returns an iterator so list size shouldn't be an issue.
>>
>>What problem are you actually trying to solve?
>>
>>Kent
>>[/color]
>
>
> Oh, you are right.
>
> Actually, it's more complicated than simple reversion. The list order
> should be somewhat "twisted" and the list is big.
>
> For example,
>
> [1,2,3,4,5,6,7,8,9,10]
>
> --> [10,9,8,7,6,1,2,3,4,5]
>
> so __getitem__(self,i) => __getitem__(self,-i-1) if i<len(size)/2,
> otherwise __getitem__(self,i-len(size)/2)
>
> I'd like to have TwistedList class that takes in an original list and
> pretends as if it is twisted actually. However, I have to have
> duplicate codes here and there to make it act like a "list", say assert
> twisted_list == [10,9,...] and for each in twisted_list and etc.
>[/color]
If you want a twisted 'view' of an existing list, then a wrapper makes most sense.

If, however, you only need the twisted version, why not simply override
list.__init__ (and extend, append etc... as required):
[color=blue][color=green][color=darkred]
>>> class rev_list(list):[/color][/color][/color]
... def __init__(self, iterable):
... list.__init__(self, iterable[::-1])
...[color=blue][color=green][color=darkred]
>>> l = rev_list([1,2,3])
>>> l[/color][/color][/color]
[3, 2, 1]

Michael

  #10  
Old July 18th, 2005, 10:57 PM
janeaustine50@hotmail.com
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

Michael Spencer wrote:[color=blue]
> janeaustine50@hotmail.com wrote:[color=green]
> > Kent Johnson wrote:
> >[color=darkred]
> >>janeaustine50@hotmail.com wrote:
> >>
> >>>p.s. the reason I'm not sticking to reversed or even reverse :[/color]
> >
> > suppose
> >[color=darkred]
> >>>the size of the list is huge.
> >>
> >>reversed() returns an iterator so list size shouldn't be an issue.
> >>
> >>What problem are you actually trying to solve?
> >>
> >>Kent
> >>[/color]
> >
> >
> > Oh, you are right.
> >
> > Actually, it's more complicated than simple reversion. The list[/color][/color]
order[color=blue][color=green]
> > should be somewhat "twisted" and the list is big.
> >
> > For example,
> >
> > [1,2,3,4,5,6,7,8,9,10]
> >
> > --> [10,9,8,7,6,1,2,3,4,5]
> >
> > so __getitem__(self,i) => __getitem__(self,-i-1) if i<len(size)/2,
> > otherwise __getitem__(self,i-len(size)/2)
> >
> > I'd like to have TwistedList class that takes in an original list[/color][/color]
and[color=blue][color=green]
> > pretends as if it is twisted actually. However, I have to have
> > duplicate codes here and there to make it act like a "list", say[/color][/color]
assert[color=blue][color=green]
> > twisted_list == [10,9,...] and for each in twisted_list and etc.
> >[/color]
> If you want a twisted 'view' of an existing list, then a wrapper[/color]
makes most sense.[color=blue]
>
> If, however, you only need the twisted version, why not simply[/color]
override[color=blue]
> list.__init__ (and extend, append etc... as required):
>[color=green][color=darkred]
> >>> class rev_list(list):[/color][/color]
> ... def __init__(self, iterable):
> ... list.__init__(self, iterable[::-1])
> ...[color=green][color=darkred]
> >>> l = rev_list([1,2,3])
> >>> l[/color][/color]
> [3, 2, 1]
>
> Michael[/color]

Thank you but your advice doesn't fit in my case since I want to keep
the memory usage and the initial time minimum. iterable[::-1] would
build another list and it would take big memory and time during
reversing if iterable were huge. (and the "iterable" wouldn't be
garbage-collected because I want to keep a reference to it)

  #11  
Old July 18th, 2005, 10:58 PM
Just
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

In article <1109208924.563510.212500@f14g2000cwb.googlegroups .com>,
janeaustine50@hotmail.com wrote:
[color=blue]
> Thank you but your advice doesn't fit in my case since I want to keep
> the memory usage and the initial time minimum. iterable[::-1] would
> build another list and it would take big memory and time during
> reversing if iterable were huge. (and the "iterable" wouldn't be
> garbage-collected because I want to keep a reference to it)[/color]

If your list contains numbers (or lists of numbers), consider using
NumPy (Numeric) or Numarray, in which seq[::-1] will actually return a
"view", and not a copy.

Just
  #12  
Old July 18th, 2005, 10:58 PM
Serge Orlov
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

janeaustine50@hotmail.com wrote:[color=blue]
> Thank you but your advice doesn't fit in my case since I want to keep
> the memory usage and the initial time minimum. iterable[::-1] would
> build another list and it would take big memory and time during
> reversing if iterable were huge. (and the "iterable" wouldn't be
> garbage-collected because I want to keep a reference to it)[/color]

You need to implement __iter__ method to pass your assert statement:
def __iter__(self):
return reversed(self)

With regards to style guide:

1. write empty subclass
class rev_subclass(list):
pass

2. print dir(rev_subclass) and write unit tests for every method. There
are 41 of them :) There is also __doc__ attribute you need to override.

3. Implement all the methods of rev_subclass to pass the tests.

Serge.

  #13  
Old July 18th, 2005, 10:58 PM
Nick Coghlan
Guest
 
Posts: n/a
Default Re: Style guide for subclassing built-in types?

janeaustine50@hotmail.com wrote:[color=blue]
> Thank you but your advice doesn't fit in my case since I want to keep
> the memory usage and the initial time minimum. iterable[::-1] would
> build another list and it would take big memory and time during
> reversing if iterable were huge. (and the "iterable" wouldn't be
> garbage-collected because I want to keep a reference to it)[/color]

1. Do you have benchmark results or a mathematical analysis to show that
duplicating the list uses too much memory, or is too slow to startup?

2. Do you have quantitative definitions for "too much" and "too slow", and
rationale to back up those numbers?

3. Do you have a benchmark to determine if attempting to reduce memory
consumption and start-up time has a detrimental effect on run-time performance?

If the answer to any of the above questions is 'no', then just do something like:

from itertools import islice, chain
def twisted_iter(orig):
halfway, skip_middle = divmod(len(orig), 2)
fwditr = islice(iter(orig), halfway + skip_middle, None)
revitr = islice(reversed(orig), halfway, None)
return chain(revitr, fwditr)

Py> from itertools import islice, chain
Py> def twisted_iter(orig):
.... halfway, skip_middle = divmod(len(orig), 2)
.... fwditr = islice(iter(orig), halfway + skip_middle, None)
.... revitr = islice(reversed(orig), halfway, None)
.... return chain(revitr, fwditr)
....
Py> list(twisted_iter(range(10)))
[4, 3, 2, 1, 0, 5, 6, 7, 8, 9]
Py> list(twisted_iter(range(11)))
[5, 4, 3, 2, 1, 0, 6, 7, 8, 9, 10]

Since twisted_iter is actually a highly-optimised twisted view of the original
list, you may want to just leave the original list alone, and create
twisted_iter's when you want them.

However, if you mainly use the twisted view, and only occasionally want the
original view, then you can twist it once, store the result, discard the
original, and twist it again to get the original back:

Py> list(twistediter(list(twistediter(range(10)))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Py> list(twistediter(list(twistediter(range(11)))))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Those benchmarks I mentioned earlier will let you know which approach is best.

No-optimisations-without-measurements-'ly,
Nick.

--
Nick Coghlan | ncoghlan@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles