I am obviously missing something fundamental here. Hopefully someone can put me right! TIA
I have an array of objects whose class contains instances of another object. But when I set a property for one of these then they all change.
class direction():
dest = -1
lock = ''
class room():
roomname = ''
desc = ''
n = direction()
s = direction()
w = direction()
e = direction()
item = ''
rooms = []
rooms.append( room() )
rooms.append( room() )
rooms.append( room() )
rooms.append( room() )
rooms.append( room() )
rooms[0].roomname = 'outside'
rooms[0].desc = ''
rooms[0].n.dest = 4
rooms[0].item = ''
rooms[1].roomname = 'hall'
rooms[1].desc = 'The hallway has doors to the east and south'
rooms[1].n.dest = 2
rooms[1].item = ''
if I iterate through the n.dest properties in the rooms list then all are returned as 2
It is as if the direction objects in each object in the rooms list are all a single instance and setting one value in one of them sets it for all of them.
-
BTW please ignore the lack of constructors - I am keeping the code simple just now and will add them later.Rich– Rich2019年04月30日 12:42:38 +00:00Commented Apr 30, 2019 at 12:42
-
1The lack of constructors is the problem.chepner– chepner2019年04月30日 12:59:31 +00:00Commented Apr 30, 2019 at 12:59
3 Answers 3
Your attributes are all declared at class level, not instance level, meaning that every instance of the class will share the same values. I think you want:
class Room():
def __init__(self):
self.roomname = ''
self.desc = ''
self.n = direction()
self.s = direction()
self.w = direction()
self.e = direction()
self.item = ''
4 Comments
rooms[1].roomname = 'hall you create a new instance attribute that will shadow the class atrribute. With rooms[1].n.dest = 2 you set a new value for the attribute dest, but this attribute belongs to an existing class level attribute n.You're missing constructors, and therefore missing instance variables
You're defining class variables, so each variable is the same between all instances
Comments
In each class, you have declared a bunch of class attributes. An assignment like rooms[0].roomname = 'outside' creates an instance attribute that shadows room.roomname. However, you never actually make any such assignment to rooms[0].n, so each assignment to something like rooms[0].n.dest is adding an instance attribute dest to the same instance of direction shared by each instance of room.
In your attempt to "simplify" your code, you've made it more complicated. Define __init__ to set your instance attributes; class attributes are not used as often.
class Direction:
def __init__(self, dest, lock=''):
self.dest = dest
self.lock = lock
class Room:
def __init__(self, roomname, desc, item=''):
self.roomname = roomname
self.desc = desc
self.n = direction()
self.s = direction()
self.w = direction()
self.e = direction()
self.item = item
rooms = []
r = Room('outside', '')
r.n.dest = 4
rooms.append(r)
r = Room('hall', 'The hallway has doors to the east and south')
r.n.dest = 2
rooms.append(r)