这两个代码应该做完全相同的事情,但第一个没有像我预期的那样工作

These two codes should do exactly the same thing, but the first one doesn't work as I expect

Python

请解释为什么这两个代码的工作方式不同.. 事实上,我正在尝试制作一种人工智能,在最初的几代人中,个体会朝着随机的方向前进。为了保持代码简单,我自己在 Brain 中提供了一些随机的 directions

有一个个人class给个人一个大脑。它还具有 returns 与 parent.

具有完全相同的大脑(意味着进入相同的方向)的 child 的功能

我有两个代码:

首先: 当 parent 中的某些方向发生变化时,child 中也会发生同样的变化(或者如果 child,它也在 parent 中发生了变化)我不想发生这种情况。

其次:这个不完全是我的(这就是为什么我真的不知道它为什么有效)但它工作得很好。 parent 中更改的某些方向在 child 和 vice-versa 中没有更改。

请有人向我解释其中的区别以及为什么第一个不起作用。非常感谢您的回答。


第一个:

class Brain():
    def __init__(self):
        self.directions = [[1, 2], [5, 3], [7, 4], [1, 5]]

class Individual():
    def __init__(self):
        self.brain = Brain()

    def getChild(self):
        child = Individual()
        child.brain = self.brain
        return child

parent = Individual()
child = parent.getChild()

parent.brain.directions[0] = [5, 2]

print(parent.brain.directions)
print(child.brain.directions)

[ [5, 2], [5, 3], [7, 4], [1, 5] ]

[ [5, 2], [5, 3], [7, 4], [1, 5] ]



第二个:

class Brain():
    def __init__(self):
        self.directions = [[1, 2], [5, 3], [7, 4], [1, 5]]

    def clone(self):
        clone = Brain()
        for i, j in enumerate(self.directions):
            clone.directions[i] = j
        return clone

class Individual():
    def __init__(self):
        self.brain = Brain()

    def getChild(self):
        child = Individual()
        child.brain = self.brain.clone()
        return child

parent = Individual()
child = parent.getChild()

parent.brain.directions[0] = [5, 2]

print(parent.brain.directions)
print(child.brain.directions)

[ [5, 2], [5, 3], [7, 4], [1, 5] ]

[ [1, 2], [5, 3], [7, 4], [1, 5] ]

在第一个代码中,设置 child.brain = self.brain 并没有达到您的预期。这是一个浅拷贝,这意味着它只是创建一个指向 Brain() 相同实例的新指针。所以现在 child.brainself.brain 都指向内存中相同的 Brain()

在第二个代码中,您正在进行深拷贝。因此,您实际上是在内存中分配另一个 Brain() 。现在 child.brainparent.brain 指向内存中它们自己单独的 Brain() 实例。

在第一种情况下,您指的是同一个对象。 尝试在第一种情况下添加以下打印语句。

print (id(parent.brain))
print (id(child.brain))

在第一种情况下对 Brain() 有新的参考。你可以看看它是如何处理的。

class Brain():
    def __init__(self):
        self.directions = [[1, 2], [5, 3], [7, 4], [1, 5]]

class Individual():
    def __init__(self):
        self.brain = Brain()

    def getChild(self):
        child = Individual()
        child.brain = Brain()
        return child

parent = Individual()
child = parent.getChild()

parent.brain.directions[0] = [5, 2]

print(parent.brain.directions)
print(child.brain.directions)