Inheriting from Python list object(type?)

M

Mangabasi

Howdy,

I would like to create a Point class that lets me use Point instances
like the following example.
p = Point(3, 4)
p.x 3
p.y 4
p.z 1
p[0] 3
p[1] 4
p[1] = 5
p.y 5

other than the x, y, z attributes, these instances should behave like
regular Python lists. I have created something like :

class Point:
def __init__(self, x, y, z = 1):
self.list = [x, y, z]

def __repr__(self):
return str(self.list)

def __str__(self):
return str(self.list)

def __getattr__(self, name):
if name == 'x':
return self.list[0]
elif name == 'y':
return self.list[1]
elif name == 'z':
return self.list[2]
else:
return self.__dict__[name]

def __setattr__(self, name, value):
if name == 'x':
self.list[0] = value
elif name == 'y':
self.list[1] = value
elif name == 'z':
self.list[2] = value
else:
self.__dict__[name] = value

def __getitem__(self, key):
return self.list[key]

def __setitem__(self, key, value):
self.list[key] = value

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

def __setslice__(self, i, j, s):
self.list[i : j] = s

def __contains__(self, obj):
if obj in self.list:
return True
else:
return False


There must be a way to inherit from the list type without having to
redefine all the methods and attributes that regular lists have.

i.e.

class Point(list):
...


Can someone provide an example?

Thanx in advance
 
J

Jerry Hill

There must be a way to inherit from the list type without having to
redefine all the methods and attributes that regular lists have.

Like this:

class Point(list):
def __init__(self, x, y, z = 1):
list.__init__(self, [x, y, z])

def __getattr__(self, name):
if name == 'x': return self[0]
if name == 'y': return self[1]
if name == 'z': return self[2]

def __setattr__(self, name, value):
if name == 'x': self[0] = value
if name == 'y': self[1] = value
if name == 'z': self[2] = value

Does that show you what you need?
 
J

Jerry Hill

When I modified this to:

class Point(list):
def __init__(self,x,y):
super(Point, self).__init__([x, y])
self.x = x
self.y = y

It worked.

Are you sure?
p = Point(10, 20)
p [10, 20]
p.x 10
p.x = 15
p [10, 20]
p[0] 10
p.x 15

That doesn't look like what you were asking for in the original post.
I'm afraid I don't know anything about numpy arrays or what special
attributes an object may need to be put into a numpy array though.
 
I

irstas

This is the winner:

class Point(list):
def __init__(self, x, y, z = 1):
super(Point, self).__init__([x, y, z])
self.x = x
self.y = y
self.z = z

def __getattr__(self, name):
if name == 'x':
return self[0]
elif name == 'y':
return self[1]
elif name == 'z':
return self[2]
else:
return self.__dict__[name]

def __setattr__(self, name, value):
if name == 'x':
self[0] = value
elif name == 'y':
self[1] = value
elif name == 'z':
self[2] = value
else:
self.__dict__[name] = value


Inheritation is an "is a" relation. Point, however, is not a list.
This adds some weird behaviour to Point:

p = Point(1,2,3)
p.append(4)
print p[3]

That makes no sense but your Point implementation allows it. This
is probably even more surprasing behaviour:

p = Point(1,2,3) + Point(4,5,6)
print p

One might expect the points to be added to Point(5,7,9), not
into a list containing [1,2,3,4,5,6].

I'd suggest you don't inherit Point from anything, and just add
an __iter__ member function that iterates through x,y and z. E.g.

def __iter__(self):
yield self.x
yield self.y
yield self.z

Then you can convert a Point p to a list by doing list(p). Or to
a tuple with tuple(p). __array__ could also be implemented for
convenince with numpy (if I understood that correctly).
 

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

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,783
Latest member
RickeyDort

Latest Threads

Top