クラスListener
を定義し、Listener
オブジェクトの辞書を作成しました。各リスナーには、それらを識別するためのid
と、リスナーが聞くartists
のリスト_artists = []
_があります。 artists
リストに何かを追加すると、参照されたインスタンスではなく、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わかりませんか?なぜこれが出力であり、代わりにどのようにして希望の出力を得ることができるのですか?ありがとうございます!
メンバーをクラス内で宣言するのではなく、__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
しかし実際に起こったことは、新しいxをa1インスタンスに入れたことです。これは、クラスメンバーの代わりに出力され、元の値を保持しています。
>>> 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]
これはPythonの微妙なことですが、理解できませんか?
微妙ではありません。非常に単純です。問題を混乱させる他の言語とは異なり、Pythonでは、クラス内で宣言するすべてがクラスに属します。クラスはオブジェクト(他のすべてと同様)であるため、これは当然のことであり、完全に有効ですしたがって、これらのメソッドはすべて、(何らかの方法で各インスタンスに魔法のようにコピーされるのではなく)クラスに属し、データ属性もそうです。
各リスナーには、それらを識別するための
id
があります
はい、__init__
の各インスタンスに1つアタッチするためです。これには何もしないクラスに属するid
があります-インスタンスを介してid
を検索するとき、インスタンス自身のid
が見つかり、クラスに属するものを非表示にします。
彼らが聴いているアーティストのリスト、アーティスト= []
ただし、クラスを介してartists
を検索すると、インスタンスにクラスがないため、クラスのartists
が見つかります。
アーティストリストに何かを追加すると、リスナークラスのすべてのインスタンスに追加されます
番号; クラス自体にが追加されます。これは、インスタンスに見つからない場合に検索される場所です。
後でインスタンスにself.artists = []
のような直接割り当てを行った場合、そのインスタンスはクラスのリストを非表示にする独自のリストを取得することに注意してください。そのコードは他のインスタンスで実行されなかったため、他のインスタンスはそうしませんでした。