附加到列表实例的对象出现在该lis的另一个实例中

2024-05-23 19:09:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我写这段代码是为了练习面向对象编程。在

在这里,我试图将一个房子定义为一个房间的列表,而每个房间则是一个设备列表(例如,灯具)。在

首先,我创建了所有的对象,然后他们将两个房间附加到房子中,并在每个房间中添加了不同的设备。很基本。在

问题是,这台设备似乎被附在两个房间里。为什么?在

代码:

#! /usr/bin/python

class House:
        def __init__(self, rooms = list()):
                self.rooms = rooms
                print('house created')


class Room:
        def __init__(self, name = 'a room', devs = list()):
            self.name = name
            self.devs = devs
            print('room ' + self.name + ' created')


class Device:
        def __init__(self, name = 'a device'):
                self.name = name
                print('device ' + self.name + ' created')


def main():
        #1
        h = House()
        r1 = Room(name = 'R1')
        r2 = Room(name = 'R2')
        d1 = Device(name = 'lamp1')
        d2 = Device(name = 'lamp2')

        #2
        h.rooms.append(r1)
        h.rooms.append(r2)

        for room in  h.rooms:
                print room.name

        print h.rooms[0]
        print h.rooms[1]
        h.rooms[1].devs.append(d1)

        #3
        for room in h.rooms:
                print room.name
                for dev in room.devs:
                        print('room ' + room.name + ' > ' + dev.name)
                        print room
                        print dev


if __name__ == '__main__' : main()

以及输出。在

^{pr2}$

请注意,d1的同一实例位于两个房间r1和r2中。在


Tags: nameselfinitmaindevicedefclassroom
3条回答

默认参数在方法声明时计算一次。然后,该值将用于对该方法的所有调用。在

关于stackoverflow exploring the reasons for this design和如何best avoid these mutable default arguments还有其他问题。在

函数的默认参数值只计算一次。这意味着House的所有实例将对self.rooms使用相同的列表实例(如果在构造中没有给出rooms参数)。以同样的方式,Room的所有实例将为self.devs共享相同的列表。在

要解决此问题,请编写如下代码:

def __init__(self, rooms = None):
    if rooms is None:
        rooms = []
    self.rooms = rooms
    print('house created')

其他班级也一样。在

def __init__(self, name = 'a room', devs = list()):
    self.name = name
    self.devs = devs
    print('room ' + self.name + ' created')

当您这样做时,list()实际上总是同一个列表。不是每次调用构造函数时都会得到一个新的空列表,而是得到相同的空列表。为了解决这个问题,你需要复制一份。在

另外,list()的习惯用法是[]。在

^{pr2}$

相关问题 更多 >