2013-06-14 38 views
8

C'è qualche magia che posso usare in Python per usare efficacemente il super costruttore semplicemente aggiungendo alcuni argomenti extra?Come passare tutti gli argomenti da __init__ a super classe

Idealmente mi piacerebbe usare qualcosa come:

class ZipArchive(zipfile.ZipFile): 
    def __init__(self, verbose=True, **kwargs): 
     """ 
     Constructor with some extra params. 

     For other params see: zipfile.ZipFile 
     """ 
     self.verbose = verbose 
     super(ZipArchive, self).__init__(**kwargs) 

e quindi essere in grado di utilizzare i parametri del costruttore originali mescolati con alcune cose in più della mia classe. In questo modo:

zip = ZipArchive('test.zip', 'w') 
zip = ZipArchive('test.zip', 'w', verbose=False) 

sto usando Python 2.6, ma se la magia può essere raggiunto solo in una maggiore versione di Python, allora io sono troppo interessato.

EDIT: Probabilmente dovrei dire che sopra non funziona. L'errore è: TypeError: __init__() takes at most 2 arguments (3 given)

+0

Ho appena aggiunto informazioni. per chiarirlo :-) – Nux

risposta

25

siete quasi arrivati:

class ZipArchive(zipfile.ZipFile): 
    def __init__(self, *args, **kwargs): 
     """ 
     Constructor with some extra params: 

     * verbose: be verbose about what we do. Defaults to True. 

     For other params see: zipfile.ZipFile 
     """ 
     self.verbose = kwargs.pop('verbose', True) 

     # zipfile.ZipFile is an old-style class, cannot use super() here: 
     zipfile.ZipFile.__init__(self, *args, **kwargs) 

Python 2 è un po 'persnickety e divertente di miscelazione *args, **kwargs e ulteriori argomenti a parola chiave con nome; la soluzione migliore è per non aggiungere ulteriori argomenti di parole chiave espliciti e basta prenderli da kwargs invece.

Il dict.pop() method rimuove la chiave dal dizionario, se presente, restituendo il valore associato o il valore predefinito specificato se mancante. Ciò significa che facciamo non passare verbose sulla super classe. Utilizzare kwargs.get('verbose', True) se si desidera verificare se il parametro è stato impostato senza rimuoverlo.

+0

Oppure 'self.verbose = kwargs.pop ('verbose', verbosedefaultvalue)' – glglgl

+0

@glglgl: anzi, molto più beter, ho dimenticato che 'pop()' ha un valore predefinito. –

+1

Puoi anche prendere in considerazione 'self.verbose = kwargs.get ('verbose', verbosedefaultvalue)' nel caso in cui tu voglia guardare args che fanno anche il metodo super-class. – Ber

Problemi correlati