在__init__中声明的变量似乎在类实例之间共享?

时间:2013-01-05 16:31:56

标签: python class shared init

我写了这段代码,我无法弄清楚我到底做错了什么。我创建了两个'Route'类的实例,并以某种方式共享'coords'列表的值。

import random

class Route():
    def __init__(self):
        self.coords = []  
        self.distance = 0
    def Generate(self, cities):
        random.shuffle(cities)
        self.coords = cities

class Citymap():
    def __init__(self, nr):
        self.Nr_of_cities = nr
        self.cities = []
    def Generate_map(self):
        for i in range(0, self.Nr_of_cities):
            self.cities.append((random.randint(0, 750), random.randint(0, 750)))


city = Citymap(6)
city.Generate_map()

a = Route()
a.Generate(city.cities)

b = Route()
b.Generate(city.cities)

print a.coords
print b.coords

a和b的输出:

[(429, 713), (336, 611), (555, 465), (397, 227), (222, 412), (491, 322)]
[(429, 713), (336, 611), (555, 465), (397, 227), (222, 412), (491, 322)]

a和b应该是不同的实例但不知何故他们最终会分享'coords'变量。有人可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

问题不在于构造函数,而是Generate函数。改变它来制作副本:

def Generate(self, cities):
    self.coords[:] = cities      # <<< note the [:]
    random.shuffle(self.coords)

否则它不仅会改变传递给它的列表,还会在self.coords中保留对列表的引用,从而导致您描述的行为。

答案 1 :(得分:1)

这很微妙,但你要分配城市数组并复制城市数组的地址。所以你没有将city.cities传递给Generate,你传递的是实际数组本身,然后在Generate函数的最后一行分配。

你可以这样做:

print id(a.coords)
print id(b.coords)

我能按照以下方式让它按预期工作:

import random
from copy import copy

class Route():
    def __init__(self):
        self.coords = []  
        self.distance = 0
    def Generate(self, cities):
        random.shuffle(cities)
        self.coords = cities

class Citymap():
    def __init__(self, nr):
        self.Nr_of_cities = nr
        self.cities = []
    def Generate_map(self):
        for i in range(0, self.Nr_of_cities):
            self.cities.append((random.randint(0, 750), random.randint(0, 750)))


city = Citymap(6)
city.Generate_map()

a = Route()
a.Generate(copy(city.cities))

b = Route()
b.Generate((city.cities))
print a.coords
print b.coords
print a
print b
print id(a.coords)
print id(b.coords)

答案 2 :(得分:0)

您必须克隆city.cities列表,否则它们将在它们之间共享:

a = Route()
a.Generate(city.cities[:])

b = Route()
b.Generate(city.cities[:])