2009-06-23 10 views
2

Je suis en train de me sauver un peu de taper en écrivant le code suivant, mais il semble que je ne peux pas le faire:python héritage attribut class

class lgrAdminObject(admin.ModelAdmin): 
    fields = ["title","owner"] 
    list_display = ["title","origin","approved", "sendToFrames"] 

class Photos(lgrAdminObject): 
    fields.extend(["albums"]) 

Pourquoi ne pas que le travail? De plus, car ils sont non fonctions, je ne peux pas faire le truc super

fields = super(Photos, self).fields 
fields.extend(["albums"]) 

Répondre

7

Héritage applique après le corps de la classe exécute. Dans le corps de la classe, vous pouvez utiliser lgrAdminObject.fields - vous êtes sûr de vouloir modifier l'attribut de la superclasse plutôt que d'en faire une copie en premier? Semble particulier ... Je commencerais avec une copie:

class Photos(lgrAdminObject): 
    fields = list(lgrAdminObject.fields) 

avant de poursuivre avec les modifications.

+0

Je donnais juste un exemple, mais vous avez raison, je voudrais copier la liste avant de la changer;) – Jiaaro

4

Avez-vous essayé?

fields = lgrAdminObject.fields + ["albums"] 

Vous devez créer un nouvel attribut de classe, pas étendre celui de la classe parente.

2

Si vous insistez pour utiliser les attributs de classe, vous pouvez référencer directement la classe de base.

class Photos(lgrAdminObject): 
    lgrAdminObject.fields.extend(["albums"]) 

Un chèque trivial suit:

>>> class B0: 
...  fields = ["title","owner"] 
...  
>>> class C1(B0): 
...  B0.fields.extend(["albums"]) 
...  
>>> C1.fields 
['title', 'owner', 'albums'] 
>>> B0.fields 
['title', 'owner', 'albums'] 
>>> 

On dirait l'attribut de base est modifié aussi bien, probablement pas ce que vous recherchez. Regardez dans la définition de la méthode exécutable (__init__(), peut-être?).

Ou (mieux?) Suivre la suggestion de @ Alex Martelli et copiez l'attribut de base:

>>> class B0: 
...  fields = ["title","owner"] 
... 
>>> class C1(B0): 
...  fields = B0.fields[:] 
...  fields.extend(["albums"]) 
...  
>>> C1.fields 
['title', 'owner', 'albums'] 
>>> B0.fields 
['title', 'owner'] 
>>> 
1

Notez également que lorsque vous avez une liste comme un attribut de classe, il appartient à la classe, et non les instances . Donc si vous le modifiez, cela changera pour toutes les instances. Il est probablement préférable d'utiliser un tuple à la place, à moins que vous n'ayez l'intention de le modifier avec cet effet (et vous devriez le documenter clairement, car c'est une cause fréquente de confusion).