2010-08-13 22 views
15

Je veux créer un namedtuple qui représente les drapeaux individuels dans un champ de bits court. J'essaye de le sous-classer de sorte que je puisse décompresser le bitfield avant que le tuple soit créé. Cependant, ma tentative actuelle ne fonctionne pas:Modifier les arguments constructeur d'un namedtuple via un sous-classement?

class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")): 
    __slots__ =() 

    def __new__(cls, status): 
     super(cls).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128) 

Maintenant, mon expérience avec super() est limitée et mon expérience avec __new__ est pratiquement inexistante, donc je ne suis pas tout à fait sûr que faire de la (à moi) erreur énigmatique TypeError: super.__new__(Status): Status is not a subtype of super. Googling et creuser dans les docs n'ont rien donné d'éclairant.

Aide?

Répondre

16

Vous aviez presque :-) Il y a seulement deux petites corrections:

  1. La nouvelle méthode a besoin d'un retour déclaration
  2. Le super appel doit avoir deux arguments, cls et État

Le code résultant ressemble à ceci:

import collections 

class Status(collections.namedtuple("Status", "started checking start_after_check checked error paused queued loaded")): 
    __slots__ =() 

    def __new__(cls, status): 
     return super(cls, Status).__new__(cls, status & 1, status & 2, status & 4, status & 8, status & 16, status & 32, status & 64, status & 128) 

Il fonctionne proprement, comme vous l'aviez prévu:

>>> print Status(47) 
Status(started=1, checking=2, start_after_check=4, checked=8, error=0, paused=32, queued=0, loaded=0) 
+4

Devrait être ' super (Statut, cls) '! – knite

10

J'éviterais super sauf si vous êtes explicitement en charge de l'héritage multiple (heureusement pas le cas ici ;-). Il suffit de faire quelque chose comme ...:

def __new__(cls, status): 
    return cls.__bases__[0].__new__(cls, 
            status & 1, status & 2, status & 4, 
            status & 8, status & 16, status & 32, 
            status & 64, status & 128) 
+0

travaillé comme un charme. Merci! –

+0

@Ben, de rien! –

+4

vous pouvez également réduire la duplication de code en utilisant ceci: 'return cls .__ bases __ [0] .__ nouveau __ (cls, * (statut & (1 << x) pour x dans la plage (0, 8)))' – thejoshwolfe