2012-03-17 13 views
12

Listener sınıfını tanımladım ve Listener nesnesi için bir sözlük oluşturdum. Her dinleyici, onları tanımlamak için bir id ve dinledikleri artists listesini içerir, artists = []. artists listesine bir şey eklemek, söz konusu örnek yerine, Listener sınıfının tüm örnekleri için ekler. Bu benim sorunum. Dinleyici sınıf olarak tanımlanırBir python sınıfının bir üyesi olarak listeleme, içeriği neden sınıfın tüm örneklerinde paylaşılıyor?

aşağıdaki gibidir:

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) 

Ve çıkış: Burada

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 

benim ayıklama testi kodudur

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'] 

My beklenen çıkışı olmasıdır son addArtist("Ace of Base", 5) çağrı, çıkış

sonuçlanır
1 
pre: [] 
post: ['Ace of Base'] 

Bu bir Python inceliği mi anlamadım? Neden bu çıktı ve bunun yerine istenilen çıktıyı nasıl alabilirim? Teşekkürler!

cevap

24

Sen üyeleri istemiyoruz sınıf içinde bildirilmek, ama sadece __init__ yönteminde ayarlayın: Eğer varsa

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 

Sonra x

class A: 
    x=5 

gibi bir sınıf üyesidir sınıf ve bu sınıfın örneklerinin bir üyesi değil.

>>> a=A() 
>>> print a.x 
5 

Ama aynı zamanda sınıfın kendisi üzerinden erişebilecek:

>>> print A.x 
5 

Hatta bu düzgün çalıştığını görünür piton size örneği aracılığıyla sınıf üyelerini erişmenizi sağlar, bu durum kafa karıştırıcı olabilir:

>>> a1=A() 
>>> a2=A() 
>>> a1.x=6 
>>> print a1.x 
6 
>>> print a2.x 
5 

ancak gerçekte oldu yerine hala orijinal değere sahip sınıf üyesi arasında basılacaktır a1 örneğine yeni bir x, koyduk ':

>>> print A.x 
5 

bir liste gibi değiştirilebilir bir şey olduğunda yalnızca bir fark görmeye başlarsınız:

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] 
4

bu Anlamıyorum Python bir incelik var mı?

Bu ince değil, oldukça basit; Sorunu akılda tutan diğer dillerden farklı olarak, Python'da sınıf içinde beyan ettiğiniz her şey sınıfa aittir. Bu doğal bir şeydir, çünkü sınıflar nesnelerdir (her şey gibi) ve böylece şeyleri birleştirmek için mükemmel bir yer. Bu nedenle, tüm bu yöntemler sınıfa aittir (her bir örneğe bir şekilde sihirli bir şekilde kopyalanmak yerine) ve aynı zamanda veri niteliklerini de yaparlar.

Her dinleyici onları tanımlamak için id sahiptir

Evet, __init__ her örneğine birini takmak çünkü. ileid sınıfına ait id ile bir ilgisi yoktur, örneğin bir örnek üzerinden id'a baktığınızda, örneğe ait olan id sınıfına ait olanı gizler. örneği değil çünkü

ve sanatçılar, dinlemek sanatçıların listesi = [] sınıfta aracılığıyla artists bakmak

Ancak, sınıf artists, bulunacak bir tane var.

sanatçı listesine şey ekleme Dinleyici sınıfına

tüm örneklerini ekler Hayır; sınıfının kendisi için sınıfına eklenmiştir; bu, örnekte bulunmadığı zaman şeylerin arandığı yerdir. Bir örnekte self.artists = [] gibi doğrudan bir ödev yaptıysanız, bu örneğin sınıfın listesini gizleyen kendi listesini alacaktır. Diğer örnekler bunu yapmaz çünkü bu kod diğer örneklerde çalıştırılmamıştır.

İlgili konular