Perché i costruttori sono effettivamente chiamati "costruttori"?
Il costruttore (denominato __new__
) crea e restituisce una nuova istanza della classe. Quindi il C.__new__
metodo di classe è il costruttore per la classe C.
Il C.__init__
metodo dell'istanza viene chiamato su un'istanza specifica, dopo che è stata creata, per inizializzarla prima di essere ritrasmessa al chiamante. Quindi quel metodo è l' inizializzatore per nuove istanze di C.
In che modo sono diversi dai metodi in una classe?
Come affermato nella documentazione ufficiale, __init__
viene richiamato dopo la creazione dell'istanza . Altri metodi non ricevono questo trattamento.
Qual è il loro scopo?
Lo scopo del costruttore C.__new__
è definire il comportamento personalizzato durante la costruzione di una nuova C
istanza.
Lo scopo dell'inizializzatore C.__init__
è definire l'inizializzazione personalizzata di ogni istanza di C
dopo che è stata creata.
Ad esempio Python ti permette di fare:
class Test(object):
pass
t = Test()
t.x = 10 # here you're building your object t
print t.x
Ma se vuoi che ogni istanza di Test
abbia un attributo x
uguale a 10, puoi inserire quel codice all'interno __init__
:
class Test(object):
def __init__(self):
self.x = 10
t = Test()
print t.x
Ogni metodo di istanza (un metodo chiamato su un'istanza specifica di una classe) riceve l'istanza come primo argomento. Questo argomento è convenzionalmente denominato self
.
I metodi di classe, come il costruttore __new__
, ricevono invece la classe come primo argomento.
Ora, se desideri valori personalizzati per l' x
attributo, tutto ciò che devi fare è passare quel valore come argomento a __init__
:
class Test(object):
def __init__(self, x):
self.x = x
t = Test(10)
print t.x
z = Test(20)
print t.x
Spero che questo ti aiuti a chiarire alcuni dubbi e, poiché hai già ricevuto buone risposte alle altre domande, mi fermo qui :)
__init__
è un inizializzatore . Il costruttore di python è__new__
. Python utilizza l'inizializzazione automatica a due fasi -__new__
restituisce un oggetto valido ma (di solito) non popolato (vedibool
per un controesempio), che poi lo ha__init__
richiamato automaticamente. Ciò evita i problemi che linguaggi come C ++ hanno con oggetti parzialmente costruiti - non ne hai mai uno in Python (sebbene possa essere parzialmente inizializzato). Non avrai quasi mai bisogno di sovrascrivere entrambi__new__
e__init__
su una classe.