2010-07-07 5 views
1

Bonjour je besoin d'un attribut de classe instancié et je fais ceci:instancié attribut class

>>> class X: 
...  def __init__(self, y=None): 
...    self.y = list() 

Est-ce ok? Si non, y a-t-il une autre façon de le faire? Je ne peux pas instancier cet attribut dans __init__ parce que j'y ajouterais plus tard.

+1

ce que vous entendez par "attribut class instancié"? vous avez déjà créé une liste –

+1

* Je ne peux pas instancier cet attribut dans '__init__' *, mais c'est ce que vous faites .... Je ne comprends pas votre question. –

+0

Est-ce la bonne façon de l'instancier? – user225312

Répondre

4

Définir le y var sur l'attribut niveau de la classe. Vous devrez l'initialiser à quelque chose, même si c'est une liste vide (comme vous le faisiez auparavant).

>>> class X: 
...  y = [] 
...  def __init__(self): 
...   pass 

mise à jour en fonction de vos commentaires:

Vous avez mentionné que vous étiez mixte sur la terminologie (je suppose entre les variables de classe et d'instance), voici donc ce qui va arriver si vous utilisez cette classe (et n'est probablement pas ce que vous voulez).

>>> class X: 
...  y = [] # Class level attribute 
...  def __init__(self): 
...    pass 
... 
>>> x = X() 
>>> x.y.append(1) 
>>> x.y 
[1] 
>>> x.y.append(2) 
>>> z = X() 
>>> z.y.append(3) 
>>> z.y 
[1, 2, 3] 
>>> X.y.append(4) 
>>> [1, 2, 3, 4] 

Notez que lorsque vous ajoutez une variable à la classe, elle reste entre les constructions. Dans le code précédent, nous avons instancié la variable x et la variable z comme une instance de X. Alors que nous avons ajouté à la variable y dans l'instance z, nous avons toujours ajouté à la variable de classe y. Note sur la toute dernière ligne (X.y.append(4)) J'ajoute un article en utilisant une référence à la classe X.

Ce que vous voulez probablement est basé hors de votre message original:

>>> class X: 
...  def __init__(self, y=None): 
...    self.y = y or list() # Instance level attribute. Default to empty list if y is not passed in. 
... 
>>> x = X() 
>>> x.y.append(1) 
>>> x.y 
[1] 
>>> z = X() 
>>> z.y.append(2) 
>>> z.y 
[2] 
>>> 
>>> s = X() 
>>> s.y 
[] 
>>> t = X(y=[10]) 
>>> t.y 
[10] 

Remarquez comment une nouvelle liste est créée avec chaque instance. Lorsque nous créons une nouvelle instance z et essayons d'ajouter à la variable y nous obtenons seulement la valeur qui a été ajoutée, plutôt que de conserver tous les ajouts existants à la liste. Dans le dernier exemple d'instanciation (t), le constructeur passe le paramètre y dans sa construction, et a donc la liste [10] comme variable d'instance y.

Espérons que cela aide. N'hésitez pas à demander plus d'incertitudes que de commentaires. Aussi, je suggère de lire sur la documentation de la classe Python here.

+0

Quel est le problème avec ma méthode de le faire? :) – user225312

+0

Vous avez dit "attribut de classe", c'est ce que j'ai fait. Si vous voulez conserver votre instance originale, je changerais le code en 'self.y = y ou list()', donc si quelqu'un passe, il passe 'y', alors il est utilisé, sinon vous créez un liste vide. – sdolan

+0

Merci et désolé de bousiller la terminologie. – user225312

2

Si vous avez besoin d'un attribut initial vide, auquel vous plus tard ajouter des éléments, faire juste ce

class X(object): 
    def __init__(self): 
     self.y = [] 

Peu de choses à noter ici (différences de votre version)

  • classe Dériver object
  • y = list() est identique à y = [] et est préféré.
  • Pas besoin d'avoir l'argument par défaut y=None, lorsque vous ne l'utilisez pas
+0

Mais ne spécifie pas explicitement: 'def __init __ (self, y)' le rend meilleur? – user225312

+0

@PulpFiction: Non. À moins que le constructeur n'utilise réellement un argument, l'argument ne devrait pas être présent. –

+0

@David: Donc utiliser y = None est une mauvaise pratique? – user225312

2

pour ajouter aux autres instructions: il existe des variables de classe et des variables d'instance, elles sont séparées et ne peuvent pas être accédées de la même manière. ex:

class foo: 
    x=[] 
    def __init__(self): 
     self.y=[] 

foo.x.append(20) 
f = foo() 
f.y.append(30) 
print f.y 
print foo.x 
print f.x 
print foo.y 
#results------------------------------- 
[30] 
[20] 
[20] 
Traceback (most recent call last): 
    File "C:\Users\adminuser\Desktop\temp.py", line 12, in <module> 
    print foo.y 
AttributeError: class foo has no attribute 'y' 
+0

Alors qu'est-ce que 'x = []' - variable de classe? Désolé mais essayant de comprendre la terminologie ici. – user225312

+0

@PulpFiction: oui, x est un attribut de classe et est partagé entre toutes les instances de la classe. Vous pouvez également y accéder sans créer d'instance. y est un attribut d'objet et un nouveau est créé pour chaque instance de la classe. –

0

Permettez-moi de mesure, la réponse Anurag Uniyal un peu

class X(object): 
    def __init__(self, y=None): 
     if y is None: 
      # y wasn't specified, create an empty list 
      self.y = [] 
     else: 
      # y was specified, use it 
      try: 
       self.y = list(y) #create y's copy so that the original 
           # variable is safe 
      except TypeError: 
       # ooops, couldn't create a list. We might warn 
       # the user or something. Oh, nevermind 
       self.y = []