我已经定义了一个类Listener
并创建了一个Listener
个对象的字典。每位听众都有id
来识别他们,以及他们收听的artists
列表,artists = []
。向artists
列表添加内容会为Listener
类的所有实例添加内容,而不是引用的实例。这是我的问题。
Listener类定义如下:
class Listener:
id = ""
artists = []
def __init__(self, id):
self.id = id
def addArtist(self, artist, plays):
print self.id # debugging...
print "pre: ", self.artists
self.artists.append(artist)
print "post: ", self.artists
这是我的调试测试代码:
def debug():
listeners = {}
listeners["0"] = Listener("0")
listeners["1"] = Listener("1")
listeners["0"].addArtist("The Beatles", 10)
listeners["0"].addArtist("Lady Gaga", 4)
listeners["1"].addArtist("Ace of Base", 5)
输出:
0
pre: []
post: ['The Beatles']
0
pre: ['The Beatles']
post: ['The Beatles', 'Lady Gaga']
1
pre: ['The Beatles', 'Lady Gaga']
post: ['The Beatles', 'Lady Gaga', 'Ace of Base']
我的预期输出是最终addArtist("Ace of Base", 5)
调用将导致输出
1
pre: []
post: ['Ace of Base']
这是Python的一个微妙之处,我不理解?为什么这是输出,我如何获得所需的输出呢?谢谢!
答案 0 :(得分:34)
您不希望在类中声明成员,只需在__init__
方法中设置:
class Listener:
def __init__(self, id):
self.id = id
self.artists = []
def addArtist(self, artist, plays):
print self.id # debugging...
print "pre: ", self.artists
self.artists.append(artist)
print "post: ", self.artists
如果您有类似
的课程class A:
x=5
然后x是该类的成员,而不是该类的实例的成员。这可能会令人困惑,因为python允许您通过实例访问类成员:
>>> a=A()
>>> print a.x
5
但您也可以通过课程本身访问它:
>>> print A.x
5
这甚至可以正常运行:
>>> a1=A()
>>> a2=A()
>>> a1.x=6
>>> print a1.x
6
>>> print a2.x
5
但实际发生的事情是你在a1实例中添加了一个新的x,而不是类成员,它仍然具有原始值:
>>> print A.x
5
当你有一些可以改变的东西时,你才开始看到差别,比如列表:
class A:
l=[]
>>> a1=A()
>>> print a1.l
[]
>>> a2=A()
>>> print a2.l
[]
>>> a1.l.append(5)
>>> print a1.l
[5]
>>> print a2.l
[5]
>>> print A.l
[5]
答案 1 :(得分:3)
这是Python的一个微妙之处,我不理解?
它不是微妙的,它很简单;与混淆问题的其他语言不同,在Python中,您在类中声明的所有内容都属于该类。这是很自然的,因为类是对象(就像其他所有东西一样),因此是一个非常有效的附加东西的地方。因此,所有这些方法都属于该类(而不是以某种方式神奇地复制到每个实例),数据属性也是如此。
每位听众都有一个
id
来识别他们
是的,因为您在__init__
中为每个实例附加一个。这与属于该类的id
没有关系 - 除了当您通过实例查找id
时,实例自己的id
将是发现,隐藏属于该类的那个。
和他们听的艺术家名单,艺术家= []
但是,当您通过课程查找artists
时,会找到“artists
”类,因为该实例没有。{/ p>
向艺术家列表添加内容会为Listener类的所有实例添加
没有;它将添加到类本身,这是在实例中找不到它们的地方。
请记住,如果您稍后在某个实例上进行了self.artists = []
之类的直接分配,那么该实例将获得隐藏该类列表的自己的列表。其他实例不会,因为该代码没有在其他实例上运行。