Python: utilizzare sempre __new__ invece di __init__?
-
01-10-2019 - |
Domanda
I capire come sia __init__
e __new__
lavoro.
Mi chiedo se c'è qualcosa __init__
può farlo __new__
non può?
vale a dire. può usare di __init__
sostituito dal modello seguente:
class MySubclass(object):
def __new__(cls, *args, **kwargs):
self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
// Do __init__ stuff here
return self
sto chiedendo come mi piacerebbe fare questo aspetto della Python OO adattarsi meglio nella mia testa.
Soluzione 2
Una possibile risposta da Guido inviare (grazie @ fraca7):
Ad esempio, nel modulo sottaceto,
__new__
viene utilizzato per creare casi in cui gli oggetti di deserializzazione. In questo caso, vengono create le istanze, ma il metodo__init__
non viene richiamato.
Tutte le altre risposte simili?
Sono accettare questa risposta come un 'sì' alla mia domanda:
mi chiedo se c'è qualcosa
__init__
può farlo__new__
non può?
Sì, a differenza __new__
, le azioni che si mette nel metodo __init__
non verrà eseguita durante il processo di deserializzazione. __new__
non può fare questa distinzione.
Altri suggerimenti
Quindi, la classe di una classe è tipicamente type
, e quando si chiama il metodo Class()
__call__()
sulle maniglie di classe di Class
che. Credo type.__call__()
è implementato più o meno in questo modo:
def __call__(cls, *args, **kwargs):
# should do the same thing as type.__call__
obj = cls.__new__(cls, *args, **kwargs)
if isinstance(obj, cls):
obj.__init__(*args, **kwargs)
return obj
La risposta diretta alla sua domanda è no, le cose che __init__()
può fare (cambio / "inizializzare" l'istanza specificata) è un sottoinsieme delle cose che __new__()
può fare (creare o altrimenti selezionare qualsiasi oggetto che vuole, fare qualsiasi cosa a quell'oggetto vuole prima che l'oggetto viene restituito).
E 'conveniente avere entrambi i metodi da usare, tuttavia. L'uso di __init__()
è più semplice (non deve creare qualsiasi cosa, non deve restituire nulla), e credo che sia buona norma usare sempre __init__()
meno che non abbiate un motivo specifico per l'uso __new__()
.
Bene, alla ricerca di __new__ vs __init__
su google mi ha mostrato questo .
Per farla breve, __new__
restituisce una nuova istanza di oggetto, mentre i rendimenti __init__
nulla e inizializza i membri della classe.
EDIT:. Per rispondere alla tua domanda in realtà, non si dovrebbe mai necessario eseguire l'override __new__
meno che non si sottoclasse tipi immutabili