Magic __init__ e metodi init regolari in una classe python

0

Il naming di un metodo normale init è solo confuso o è un errore?

class A:
    def __init__(self, x):
        self.x = x

    def init(self, y):
        self.y = y**2

    def reset(self):
        self.y = 0

Ho riscontrato una tale costruzione durante la revisione. Dovrei contrassegnare è come un problema?

    
posta hans 23.04.2018 - 14:03
fonte

4 risposte

2

Suggerirei di utilizzare setup anziché init per rimuovere qualsiasi ambiguità per il lettore. Mentre il codice sintatticamente corretto, illeggibile / ambiguo risulta in prodotti più difficili da gestire.

Inoltre, se tali metodi esistono in una classe ( init , reset , setup ...), cerco sempre di usarli nel costruttore stesso poiché di solito sono destinati a lasciare l'oggetto in uno stato conosciuto Ad esempio:

def __init__(self, x):
  self.reset()
  self.x = x

Questo aiuta a ridurre la duplicazione del codice e a semplificare i possibili stati in cui un oggetto può trovarsi.

    
risposta data 23.04.2018 - 16:01
fonte
3

Should I mark is as an issue?

Questo dipende molto dallo standard di codifica che stai utilizzando.

È confuso? Sì, per l'umano. Soprattutto nelle conversazioni verbali, dovendo chiarire se si intende __init__ vs init si sprecherà il tempo delle persone.

Se vuoi sfidare questa pratica, utilizza le linee guida per la denominazione degli standard di codifica. Molte specie standard di codifica che i nomi dovrebbero essere chiari e non ambigui, e nomi come questo sono ambigui per l'umano.

È un errore? No. Il parser e l'interprete python non eseguiranno l'errore, in quanto non è ambiguo. Per il compilatore / interprete Python, questi sono inequivocabili e c'è una chiara differenza tra __init__ e init .

    
risposta data 23.04.2018 - 14:31
fonte
2

Un problema con questa classe è che reset non dà come risultato una A di "appena costruita", che probabilmente sorprenderà le persone.

Se fosse o

class A:
    def __init__(self, x):
        self.x = x

    def init(self, y):
        self.y = y**2

    def reset(self):
        del(self.y)

o (più preferibilmente)

class A:
    def __init__(self, x):
        self.x = x
        self.y = 0

    def init(self, y):
        self.y = y**2

    def reset(self):
        self.y = 0

quindi sarebbe meno cattivo .

Detto questo, non mi piace nessuna classe che abbia un setup , gather members , init o qualunque metodo denominato, che gli utenti devono chiamare prima che lo scopo reale della classe possa essere Usato. Se hai veramente bisogno dell'inizializzazione a due fasi, restituisci un oggetto factory dalla prima chiamata e istanzia solo il secondo

class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y**2
    # members can assume y exists

def defferedA(x):
    def inner(y):
        return A(x, y)
    return inner
    
risposta data 23.04.2018 - 14:37
fonte
1

Questo non ha senso.

Che cosa è chiamato init a fare oltre a inizializzare un oggetto con uno stato iniziale , che è, cosa fa un costruttore, che a sua volta è, che cosa __init__ dovrebbe fare in questo caso?

Nel contesto indicato, init_y dovrebbe rendere (più) un senso.

Forse classmethods ti aiutano in questo contesto - ma il tuo esempio è quindi il tuo esempio conteso, non lo so.

    
risposta data 23.04.2018 - 14:38
fonte

Leggi altre domande sui tag