Skip to main content
 首页 » 编程设计

具有随机属性的对象的Python列表

2025年05月04日10shanyou

(编辑:randrange 只是 random.randrange,我没有写自己的 RNG)

我正在尝试创建我定义的类的实例列表。这是整个类(class)(应要求):

from random import randrange 
 
class Poly: 
    points = [0] * 8 
    fill = 'red' 
    alpha = 1.0 
 
    def __init__(self, width=100, height=100): 
        for i in range(0, 8, 2): 
            self.points[i] = randrange(width) 
            self.points[i+1] = randrange(height) 
        self.alpha = random() 
        return 

似乎工作正常:

>>> for i in range(5): 
        Poly().points 
 
[28, 64, 93, 26, 15, 31, 44, 50] 
[24, 14, 47, 14, 35, 17, 63, 62] 
[99, 28, 90, 29, 56, 59, 57, 33] 
[62, 56, 48, 28, 40, 73, 70, 99] 
[99, 32, 27, 99, 42, 57, 86, 12] 

但是如果我尝试创建这些对象的列表,我会得到单独的实例(不同的内存地址),但它们都具有相同的随机值:

>>> p = [] 
>>> for i in range(5): 
        p.append(Poly()) 
 
>>> p 
[<gen_image.Poly instance at 0x02D773C8>, <gen_image.Poly instance at 0x02D77FD0>, <gen_image.Poly instance at 0x0321D030>, <gen_image.Poly instance at 0x02D51E40>, <gen_image.Poly instance at 0x02D51DA0>] 
 
>>> for poly in p: 
        print poly.points 
 
[75, 18, 5, 76, 6, 64, 95, 54] 
[75, 18, 5, 76, 6, 64, 95, 54] 
[75, 18, 5, 76, 6, 64, 95, 54] 
[75, 18, 5, 76, 6, 64, 95, 54] 
[75, 18, 5, 76, 6, 64, 95, 54] 

这是怎么回事?做我想做的事情的正确方法是什么?

请您参考如下方法:

将数组的创建移动到 __init__ 方法中。

您正在使用所有对象之间的共享数组。

第一个显示不同的原因是您在构造新的 Poly 对象之前打印了该数组的内容,从而破坏了数组内容。如果您将它们放在身边并稍后检查它们,它们看起来都与您上次生成的内容相同。

哦,发帖时尽量不要简化代码。始终发布可重现问题的完整但简短的程序。

这是一个简短但完整的程序,它演示了您遇到的问题:

from random import randrange 
class Poly: 
    points = [0]*8 
 
    def __init__(self, width=100, height=100): 
        for i in range(0, 8, 2): 
            self.points[i] = randrange(width) 
            self.points[i+1] = randrange(height) 
        return 
 
p1 = Poly() 
print "p1:", p1.points 
p2 = Poly() 
print "p2:", p2.points 
print "p1:", p1.points 

示例输出:

[C:\Temp] test.py 
p1: [19, 5, 1, 46, 93, 18, 18, 57] 
p2: [92, 71, 42, 84, 54, 29, 27, 71] 
p1: [92, 71, 42, 84, 54, 29, 27, 71] 

注意 p1 是如何变化的。

固定代码可以很简单:

from random import randrange 
class Poly: 
    def __init__(self, width=100, height=100): 
        self.points = [0]*8 
        for i in range(0, 8, 2): 
            self.points[i] = randrange(width) 
            self.points[i+1] = randrange(height) 
        return 

尽管我更喜欢 @Doug 的附加变体发布here