【问题标题】:Variable declared in __init__ seems to be shared between class instances?__init__ 中声明的变量似乎在类实例之间共享?
【发布时间】:2013-01-05 16:31:55
【问题描述】:

我写了这段代码,但我不知道我到底做错了什么。我创建了“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' 变量。有人可以帮帮我吗?

【问题讨论】:

    标签: python class shared init


    【解决方案1】:

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

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

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

    【讨论】:

    • 也谢谢你!没想到这么简单:/
    【解决方案2】:

    这很微妙,但是您分配了城市数组并复制了城市数组的地址。所以你没有将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)
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 谢谢!这解决了它:) 我想我肯定会重写整个代码
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      • 2012-02-10
      • 2019-02-21
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多