Brian van den Broek wrote:
Hi all,

I'm trying to figure out how to subclass the list built-in.

.>>> class my_list(list):
def __init__(self, sequence=None):
list.__init__(self, sequence)
self.spam = 1
.>>> mine = my_list((1,2,3,4))
.>>> mine.append(42)
.>>> mine
[1, 2, 3, 4, 42]
.>>> type(mine)
<class '__main__.my_list'>
.>>> damn = mine[1:3]
.>>> type(damn)
<type 'list'>
.>>> damn
[2, 3]
.>>>


I had thought that by subsclassing list I got all list-like properties
for free. Append (among others) are available for my_list instances.
But slicing returns a list, rather than a my_list. I can see that this
is list-like in it's way, but I'd rather have be so in mine ;-)

The problem is that the list methods that return a new list don't know to return an object of your class. You will have to override those methods with a new method that converts the new list to an instance of my_list. Or you can use UserList which does this for you:


class my_list(list):
    def __init__(self, sequence=None):
        list.__init__(self, sequence)
        self.spam = 1

    def __getslice__(self, i, j):
        return my_list(list.__getslice__(self, i, j))

print 'Subclass list:'
mine = my_list((1,2,3,4))
mine.append(42)
print 'mine:', mine
print 'type(mine):', type(mine)
print

damn = mine[1:3]
print 'damn', damn
print 'type(damn):', type(damn)
print

from UserList import UserList
class my_list2(UserList):
    def __init__(self, sequence=None):
        UserList.__init__(self, sequence)
        self.spam = 1

print 'Subclass UserList:'
mine = my_list2((1,2,3,4))
mine.append(42)
print 'mine:', mine
print 'mine.__class__:', mine.__class__
print

damn = mine[1:3]
print 'damn', damn
print 'damn.__class__:', damn.__class__

prints:
Subclass list:
mine: [1, 2, 3, 4, 42]
type(mine): <class '__main__.my_list'>

damn [2, 3]
type(damn): <class '__main__.my_list'>

Subclass UserList:
mine: [1, 2, 3, 4, 42]
mine.__class__: __main__.my_list2

damn [2, 3]
damn.__class__: __main__.my_list2

If you decide to stick with subclassing list, UserList can still be your guide for which methods need wrappers. Look for the calls to self.__class__() in UserList.py.

I've read in the docs that UserList is discouraged, and in the Nutshell that the __getslice__, etc. special methods are depreciated.

So, how can I get slicing to preserve the my_list type? And why does
the above class get so much for free, but not slicing?

Best, and thanks to all,

Brian vdB


_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor



_______________________________________________
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor

Reply via email to