Python对象包含一个对象数组时出现问题

14

可能是重复问题:
Python中的静态类变量
Python面向对象编程和列表


我想知道是否能在这方面得到一些帮助。

我正在使用Python,并且在我正在开发的一个小程序中遇到了一个难以解决的障碍。以下是我的问题(使用一个非常简单且不相关的示例):我有一个类:

class dog:
    name = ''
    friends = []

我从中制作了几个物品:

fido = dog()
rex = dog()

接下来就是我卡住的地方了。我不知道为什么会出现这种情况,也还没有想到解决办法。我猜测我的某些理解可能不够充分,如果有任何解释,那就太好了。所以这就是我的问题:如果我将一个对象附加到另一个对象上(似乎应该完全没问题),

fido.friends.append(rex)

...事情变得混乱了。就像你在这里看到的一样:

>>> fido.friends.append(rex)
>>> fido.friends
[<__main__.dog instance at 0x0241BAA8>]
>>> rex.friends
[<__main__.dog instance at 0x0241BAA8>]
>>> 

那对我来说毫无意义。难道只有fido.friends里面应该有东西吗?即使我创建一个新对象:

rover = dog()

它里面有一个狗实例,我们可以看到这是我们的“rex”对象。

>>> rex.name = "rex"
>>> fido.friends[0].name
'rex'
>>> rex.friends[0].name
'rex'
>>> rover.friends[0].name
'rex'
>>> 

这个东西现在一点也不合理,我希望能得到帮助。我已经找了好一阵子尝试寻找解释,但没有找到。如果有我忽略的类似问题,那我很抱歉。

4个回答

7
如果每只狗都应该有自己的朋友列表,那么你需要使用实例属性:
class Dog(object):

    family = 'Canidae' # use class attributes for things all instances share 

    def __init__(self, name):
        """ constructor, called when a new dog is instantiated """
        self.name = name
        self.friends = []

    def __repr__(self):
        return '<Dog %s, friends: %s>' % (self.name, self.friends)

fido = Dog('fido')
rex = Dog('rex')

fido.friends.append(rex)
print(fido) # <Dog fido, friends: [<Dog rex, friends: []>]>

您使用的是class属性(该值在实例之间共享)。更多信息:

哇,谢谢Miku!非常感谢你那么快速、好的回答。 - A'nW

3

在Python中,声明在类内部而不附加到实例的变量是静态变量。


4
Python没有使用"static"这个词来区分这些概念。 - Ned Batchelder

1
为了避免这种情况,将变量声明放在__init__函数内部,像这样:
class Dog:
    def __init__(self):
        self.name = ''
        self.friends = []

1

实现您想要做的正确方法是使用__init__方法:

>>> class dog:
       def __init__(self):
           self.f = []


>>> a = dog()
>>> b = dog()
>>> a.f.append(b)
>>> a.f
[<__main__.dog instance at 0x02DA6F08>]
>>> c = dog()
>>> c.f
[]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接