Hamish McKenzie <[EMAIL PROTECTED]> writes: > I want to write a Vector class and it makes the most sense to just > subclass list. I also want to be able to instantiate a vector using > either: > > Vector( 1, 2, 3 ) > OR > Vector( [1, 2, 3] ) > > > so I have this: > > class Vector(list): > def __new__( cls, *a ): > try: > print a > return list.__new__(cls, a) > except: > print 'broken' > return list.__new__(cls, list(a)) > > > doing Vector( 1, 2, 3 ) on this class results in a TypeError - which > doesn't seem to get caught by the try block (ie "broken" never gets > printed, and it never tries to > > I can do pretty much the exact same code but inheriting from tuple > instead of list and it works fine. > > is this a python bug? or am I doing something wrong?
You're doing something wrong! When you call Vector.__new__(cls, *a), this creates a new list object (call it L) and then calls Vector.__init__(L, *a) automatically, falling back to list.__init__(L, *a) (which won't work when a has more than one element). In fact list initialisation is done in list.__init__, not in list.__new__ (as opposed to tuple initialisation because tuples are immutable). A solution: >>> class Vector(list): ... def __init__(self, *args): ... try: ... list.__init__(self, *args) ... except TypeError: ... list.__init__(self, args) ... >>> Vector([1,2,3]) [1, 2, 3] >>> Vector(1,2,3) [1, 2, 3] >>> Vector(1) [1] >>> Vector() [] HTH -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list