Rich
Rich

Reputation: 27

nested object in a class Python

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.

Upvotes: 0

Views: 1456

Answers (3)

chepner
chepner

Reputation: 530920

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)

Upvotes: 0

OneCricketeer
OneCricketeer

Reputation: 191681

You're missing constructors, and therefore missing instance variables

You're defining class variables, so each variable is the same between all instances

Upvotes: 1

brunns
brunns

Reputation: 2764

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 = ''

Upvotes: 1

Related Questions