正在重置python中的实例变量

时间:2013-12-21 01:41:25

标签: python instance-variables

在下面的代码中,我有一个填充的列表。 填充后,我再次访问它,但列表重置。

为什么会这样?

#Yonatan Oren 12/20/2013
#NIFTY GA Problem
from random import shuffle, randint, randrange

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def getDistance(self, point):
        distance = (((point.getX() - self.x) ** 2) + ((point.getY() - self.y) ** 2)) ** (0.5)
        return distance

class Value:
    def __init__(self, pointsList):
        self.pointsList = pointsList
        self.fitness = 0

    def getFitness(self):
        #add up all of the distances
        fitness = sum([a.getDistance(b) for a,b in zip(*[self.pointsList[i:] for i in range(2)])])
        return fitness

    def getPointsList(self):
        return self.pointsList

    def __lt__(self, other):
        return self.getFitness() < other.getFitness()



class Environment:

    def __init__(self):
        self.values = []

    def createNewEnvironment(self, pointsList): 
        self.pointsList = pointsList

        #create 10 new organisms
        for i in range(10):
            org = Value(pointsList)
            print org.getFitness()
            self.values.append(org)
            shuffle(pointsList)

        for o in self.values:
            print "point_listed: %s" % o.getFitness()


env = Environment()
env.createNewEnvironment([Point(0,0), Point(5,0), Point(10,0), Point(10,5), Point(10,10), Point(5,10), Point(0, 10), Point(0, 5), Point(0,0)])

这是输出:

40.0
75.3224755112
76.7924273619
56.1803398875
67.6831552862
84.7542230981
79.7542230981
57.3935433231
75.6120874744
70.6120874744
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343
point_listed: 82.7160188343

如您所见,所有值都重置为“82.7160188343”,我甚至都不知道 那个号码来自哪里。

有什么想法吗?

感谢。

1 个答案:

答案 0 :(得分:3)

您正在创建一大堆共享相同pointsList的值。

并不是他们的实例变量被重置,而是所有这些变量都是完全相同的值的名称,所以当你改变那个值时,他们都会看到它。


在此代码中:

self.pointsList = pointsList

#create 10 new organisms
for i in range(10):
    org = Value(pointsList)
    print org.getFitness()
    self.values.append(org)
    shuffle(pointsList)

...每个Value(pointsList)构建一个具有相同Value的新pointsList对象。在Value.__init__内,它不会复制该列表,只是这样做:

    self.pointsList = pointsList

所以,他们最终只是指同一个名单。


您可能想要做以下三件事之一:

  • 复制Value.__init__内的列表(例如self.pointsList = pointsList[:])。
  • 将副本传递给 Value.__init__(例如org = Value(pointsList[:]))。
  • 每次循环创建一个新列表,而不是一遍又一遍地重复使用相同的列表。

我认为其中第三个在您的用例中最干净。

我写了一个shuffled函数,它返回一个新的混洗副本:

def shuffled(seq):
    retval = list(seq)
    shuffle(retval)
    return retval

...所以你可以这样做:

self.pointsList = pointsList

#create 10 new organisms
for i in range(10):
    pointsList = shuffled(pointsList)
    org = Value(pointsList)
    print org.getFitness()
    self.values.append(org)