2008-11-21 12 views
2
class Ball: 
    a = [] 
    def __init__(self): 
    pass 

    def add(self,thing): 
    self.a.append(thing) 

    def size(self): 
    print len(self.a) 

for i in range(3): 
    foo = Ball() 
    foo.add(1) 
    foo.add(2) 
    foo.size() 

j'attendre à un retour de:Pourquoi les nouvelles instances d'une classe partagent-elles des membres avec d'autres instances?

2 
2 
2 

Mais je reçois:

2 
4 
6 

Pourquoi est-ce? J'ai trouvé qu'en faisant a = [] dans le init, je peux contourner ce problème, mais je ne comprends pas pourquoi.

Répondre

4

doh

Je viens de comprendre pourquoi.

Dans le cas ci-dessus, le a est un attribut de classe, pas un attribut de données - ceux-ci sont partagés par toutes les billes(). Commenter le a = [] et le placer dans le bloc init signifie qu'il s'agit d'un attribut de données à la place. (Et, je ne pouvais pas y accéder alors avec foo.a, ce que je ne devrais pas faire de toute façon.) Il semble que les attributs de classe agissent comme des attributs statiques de la classe, ils sont partagés par toutes les instances.

Whoa.

Une question cependant: CodeCompletion suce comme ceci. Dans la classe foo, je ne peux pas faire de self (variable), car elle n'est pas définie automatiquement - elle est définie par une fonction. Puis-je définir une variable de classe et la remplacer par une variable de données?

+0

C'est probablement à votre éditeur ... quel éditeur et quelle plateforme? –

+0

La complétion de code est difficile à implémenter sous Python. – user32141

+0

Veuillez poser une nouvelle question sur l'attribut classe/instance pour l'achèvement du code. – ddaa

2

Qu'est-ce que vous voulez sans doute faire est:

class Ball: 
    def __init__(self): 
    self.a = [] 

Si vous utilisez juste a = [], il crée une variable locale dans la fonction __init__, qui disparaît lorsque la fonction retourne. Assigner à self.a en fait une variable d'instance qui est ce que vous recherchez. Pour un gotcha semi-connexe, voir comment vous pouvez change the value of default parameters for future callers.

1

"Puis-je définir une variable de classe et la remplacer par une variable de données?"

Non. Ce sont des choses séparées. Une variable de classe existe précisément une fois - dans la classe.

Vous pourriez - pour terminer l'achèvement du code - commencer avec certaines variables de classe, puis supprimer ces lignes de code après avoir écrit votre classe. Mais chaque fois que vous oubliez de faire cela, rien de bon n'arrivera.

Il est préférable d'essayer un autre IDE. Les complétions de code de Komodo Edit semblent raisonnables.

Si vous avez tellement de variables avec des noms aussi longs que la complétion de code est réellement utile, vous devriez peut-être réduire la taille de vos classes ou utiliser des noms plus courts. Sérieusement.

Je trouve que lorsque vous arrivez à un endroit où la complétion du code est plus utile qu'agace, vous avez dépassé le seuil de complexité «gardez tout dans mon cerveau». Si la classe ne rentre pas dans mon cerveau, c'est trop complexe.