附加到列表实例的对象出现在该列表的不同实例中

发布于 2024-08-14 05:47:35 字数 1859 浏览 9 评论 0原文

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

在这里,我尝试将房屋定义为房间列表,将每个房间定义为设备列表(例如灯)。

首先,我创建了所有对象,并将两个房间附加到房子上,并为每个房间附加了不同的设备。非常基本。

问题是该设备似乎被附加到两个房间。这是为什么?

代码:

#! /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()

以及输出。

house created
room R1 created
room R2 created
device lamp1 created
device lamp2 created
R1
R2
<__main__.Room instance at 0xb7d8a58c>
<__main__.Room instance at 0xb7d8a5ac>
R1
room R1 > lamp1
<__main__.Room instance at 0xb7d8a58c>
<__main__.Device instance at 0xb7d8a5cc>
R2
room R2 > lamp1
<__main__.Room instance at 0xb7d8a5ac>
<__main__.Device instance at 0xb7d8a5cc>

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

I was writing this little piece of code as an exercise in object-oriented programming.

Here I'm trying to define a house as a list of rooms and each room as a list of devices (lamps, for example).

First I created all the objects and them appended the two rooms to the house and a different device to each room. Pretty basic.

The problem is that it seems that the device is being appended to both rooms. Why is that?

The code:

#! /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()

And the output.

house created
room R1 created
room R2 created
device lamp1 created
device lamp2 created
R1
R2
<__main__.Room instance at 0xb7d8a58c>
<__main__.Room instance at 0xb7d8a5ac>
R1
room R1 > lamp1
<__main__.Room instance at 0xb7d8a58c>
<__main__.Device instance at 0xb7d8a5cc>
R2
room R2 > lamp1
<__main__.Room instance at 0xb7d8a5ac>
<__main__.Device instance at 0xb7d8a5cc>

Note that the same instance of d1 is in both rooms, r1 and r2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清风疏影 2024-08-21 05:47:35

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

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

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

对于其他类也是如此。

Default parameter values for functions are evaluated only once. This means that all instances of House will use the same list instance for self.rooms (if rooms parameter wasn't given in construction). In the same manner, all instances of Room will share the same list for self.devs.

To solve this, write the code like this:

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

And the same thing for the other classes.

梦与时光遇 2024-08-21 05:47:35

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

stackoverflow上还有其他问题探索这种设计的原因以及如何最好地避免这些可变的默认参数

The default argument is evaluated once, at the point of declaration of the method. That value is then used in all calls to the method.

There are other question on stackoverflow exploring the reasons for this design and how to best avoid these mutable default arguments.

梦罢 2024-08-21 05:47:35
def __init__(self, name = 'a room', devs = list()):
    self.name = name
    self.devs = devs
    print('room ' + self.name + ' created')

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

另外,list() 更惯用的写法是 []

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

When you do this list() actually is always the same list. You don't get a new empty list each time the constructor is called, you get the same empty list. To fix that you'll want to make a copy.

Also list() is more idiomatically written as [].

def __init__(self, name='a room', devs=[]):
    self.name = name
    self.devs = list(devs)
    print('room ' + self.name + ' created')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文