2013-10-10 7 views
71

ho diviso il mio costruttore della classe facendolo chiamare molteplici funzioni, in questo modo:Istanza Attributo nome_attributo definito al di fuori __init__

class Wizard: 
    def __init__(self, argv): 
     self.parse_arguments(argv) 
     self.wave_wand() # declaration omitted 

    def parse_arguments(self, argv): 
     if self.has_correct_argument_count(argv): 
      self.name = argv[0] 
      self.magic_ability = argv[1] 
     else: 
      raise InvalidArgumentsException() # declaration omitted 

# ... irrelevant functions omitted 

Mentre il mio interprete felicemente eseguito il mio codice, pylint ha una lamentela:

Instance attribute attribute_name defined outside __init__

Una ricerca rapida di Google è attualmente inutile. Mantenere tutta la logica del costruttore in __init__ sembra non organizzata, e anche disattivare l'avviso di Pylint sembra un hack-ish.

Che cos'è il/Pythonic modo risolvere questo problema?

+4

L'avviso dice solo quello che dice. Penso che violi [POLS] (http://en.wikipedia.org/wiki/Principle_of_least_astonishment) se si inizializzano le variabili di istanza di fatto all'esterno del costruttore. Prova a inline 'parse_arguments' o usa i valori di ritorno della funzione in' __init__' per inizializzare le variabili e pylint sarà felice, suppongo. – miku

risposta

17

È sufficiente restituire una tupla da parse_arguments() e scompattarla in attributi all'interno di __init__ secondo necessità.

Inoltre, si consiglia di utilizzare Eccezioni anziché utilizzare exit(1). Si ottiene traceback, il codice è riutilizzabile, ecc

class Wizard: 
    def __init__(self, argv): 
     self.name,self.magic_ability = self.parse_arguments(argv) 

    def parse_arguments(self, argv): 
     assert len(argv) == 2 
     return argv[0],argv[1] 
+0

Poiché questo è un programma relativamente semplice e il codice principale costruirà un singolo 'Wizard' (la classe principale), ho capito che le eccezioni erano eccessive. –

+1

@StevenLiao va tutto bene, ma è ancora più leggibile, con meno linee di codice e sviluppa buone abitudini per il futuro. Sta a te. – roippi

+0

OK, ma cosa succede se si desidera aggiungere quegli attributi chiamando parse_arguments all'oggetto in circostanze particolari? In questo caso l'impostazione degli attributi pari a Nessuno è una soluzione migliore. – Soldalma

71

L'idea alla base di questo messaggio è per il bene di leggibilità. Ci aspettiamo di trovare tutti gli attributi che un'istanza può avere leggendo il suo metodo __init__.

Si può comunque voler dividere l'inizializzazione in altri metodi. In tal caso, è sufficiente assegnare attributi a None (con un po 'di documentazione) nel __init__ quindi chiamare i metodi di inizializzazione secondaria.