Changing the attributes of an object in a for loop

Question:

"Cube" object is defined as a list of 6 "Face" objects (squares). (im only using 2 until rotation works)

class Face():
    def __init__(self, center, anglex = 0, angley = 0, color = (255,255,255),):
        self.center = center
        self.anglex = anglex
        self.angley = angley
        self.color = color

    def setAngle(self, anglex, angley):
        self.anglex = anglex
        self.angley = angley
        
    def setCenter(self, cx, cy):
        self.center[0] = cx
        self.center[1] = cy



class Cube():
    def __init__(self, center):
        self.center = center
        
        face1 = Face(center, 0, 0, (255,0,0))
        face6 = Face(center, 180, 0, (0))
        
        #self.faces = [face1, face2, face3, face4, face5, face6]
        self.faces = [face1, face6]


height = 900
width = 1500
screen = pygame.display.set_mode([width, height])

cube = Cube([width/2, height/2])


When I try to change the center and angle of a face to "rotate" it, the attributes don’t seem to update properly as both faces now have the same angle/center. I’ve tried changing it with

for face in cube.faces:
        ax = (face.anglex + varx)%360
        face.setAngle(ax, face.angley)
        
        cx = width/2 + math.sin(math.radians(face.anglex))*50
        face.setCenter(cx, face.center[1])
        
        print(face.center[0])

If I print inside the loop, each face has the proper angle/center, however outside the loop,

for face in cube.faces:
        ax = (face.anglex + varx)%360
        face.setAngle(ax, face.angley)
        
        cx = width/2 + math.sin(math.radians(face.anglex))*50
        face.setCenter(cx, face.center[1])
        
for face in cube.faces:
        print(face.center[0])

both faces have the same angle/center. I’m guessing I don’t fully understand how object/class attributes work, so can someone please explain?

Asked By: marcoG

||

Answers:

Your objects all share the same center list:

cube = Cube([width/2, height/2])

The list [width/2, height/2] is shared, so when updated, all objects see the same change.

I suggest letting all objects make a copy:

class Face():
    def __init__(self, center, anglex = 0, angley = 0, color = (255,255,255),):
        self.center = center[:]
        ...

class Cube():
    def __init__(self, center):
        self.center = center[:]
        ...

Having said that, its not clear why Cube keeps a copy of center

Answered By: quamrana
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.