class MyList(list): Is this ok?

M

Martin Bless

Please have a look at my little program below. It works as expected
but I still feel very unsure when inheriting from builtin types.

Do I need line #1?

Is line #2 ok? Why? I came to this one more by trial and error than by
conclusion. My fingers wanted to write "self.append(v)" which creates
a nice infinite loop ...

I have read the article about "Unifying types and classes" by GvR
http://www.python.org/2.2/descrintro.html several times but probably
would need more practical examples or another tutorial.

Martin



import csv,sys

class ColumnCollector(list):

def __init__(self):
self.sums = []
list.__init__(self) #1

def append(self, v, calc=None):
list.append(self,v) #2
i = len(self)-1
try:
self.sums
except IndexError:
self.sums.append(0)
if calc:
if "sum" in calc:
self.sums += v

if 1 and __name__=="__main__":
print
csvw = csv.writer(sys.stdout)
cc = ColumnCollector()
for rownum in range(4):
cc.append(1,"sum")
cc.append(2,"sum")
cc.append(3,"sum")
csvw.writerow(cc)
del cc[:]
print "totals:"
csvw.writerow(cc.sums)
""" Should print:
1,2,3
1,2,3
1,2,3
1,2,3
totals:
4,8,12
"""
 
C

Christopher T King

import csv,sys

class ColumnCollector(list):

def __init__(self):
self.sums = []
list.__init__(self) #1

This is perfectly acceptable, though the new-style way to do this is with
the slightly messier line:
super(ColumnCollector,self).__init__()
def append(self, v, calc=None):
list.append(self,v) #2

Same applies here:
super(ColumnCollector,self).append(v)

What you have now though is effectively the same thing as using the
super() calls.
 
D

Duncan Booth

(e-mail address removed) (Martin Bless) wrote in
Do I need line #1?

Practically, no you don't although it is cleaner if you do. The list
initialiser would be needed if you were allowing a non-empty list to be
created.
Is line #2 ok? Why? I came to this one more by trial and error than by
conclusion. My fingers wanted to write "self.append(v)" which creates
a nice infinite loop ...
In general:

self.method(parms)

can be regarded as shorthand for:

type(self).method(self, parms)

So, if you called "self.append(v)" this would be the same as calling
"ColumnCollector.append(self, v)" which as you noticed creates an infinite
loop. You need to force the call to happen on the base class, which means
you can't use the shorthand form.

There are two ways to force a call to act on a baseclass method. The usual
way is what you came up with, just name the baseclass explicitly:

list.append(self, v)

The other way is to use the super builtin:

super(ColumnCollector, self).append(self, v)

Using super ensures that the code will continue to work if anyone starts
trying to multiply inherit from both your class and another class
inheriting from list. However, unless you wrote your class with that usage
in mind the extra complexity is not usually worthwhile (and besides,
something else would almost certainly break).
 
M

Martin Bless

Duncan Booth said:
In general:

self.method(parms)

can be regarded as shorthand for:

type(self).method(self, parms)

Aah, that's it. Thanks.
The other way is to use the super builtin:

super(ColumnCollector, self).append(self, v)

Ok, I'll have to learn more about super().

Thank you,

Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,661
Latest member
sxarexu

Latest Threads

Top