Ho riscontrato uno strano bug in python dove l'utilizzo del metodo __new__
di una classe come factory porterebbe al metodo __init__
della classe istanziata da chiamare due volte.Utilizzo di un metodo di classe '__new__ come factory: __init__ viene chiamato due volte
L'idea era originariamente di utilizzare il metodo __new__
della classe madre per restituire un'istanza specifica di uno dei suoi figli in base ai parametri che vengono passati, senza dover dichiarare una funzione di fabbrica al di fuori della classe.
So che l'utilizzo di una funzione di fabbrica sarebbe il miglior modello di progettazione da utilizzare qui, ma cambiare il modello di progettazione a questo punto del progetto sarebbe costoso. La mia domanda quindi è: c'è un modo per evitare la doppia chiamata a __init__
e ottenere solo una singola chiamata a __init__
in uno schema simile?
class Shape(object):
def __new__(cls, desc):
if cls is Shape:
if desc == 'big': return Rectangle(desc)
if desc == 'small': return Triangle(desc)
else:
return super(Shape, cls).__new__(cls, desc)
def __init__(self, desc):
print "init called"
self.desc = desc
class Triangle(Shape):
@property
def number_of_edges(self): return 3
class Rectangle(Shape):
@property
def number_of_edges(self): return 4
instance = Shape('small')
print instance.number_of_edges
>>> init called
>>> init called
>>> 3
Qualsiasi aiuto molto apprezzato.
Grazie mille, questo ha risolto il mio problema perfettamente. – xApple
Non sarebbe meglio usare 'return Rectangle .__ new __ (Rectangle)' perché questo garantirebbe che '__new__' di' Rectangle' venga chiamato se è definito? –
@Georg, se lo farai dovrai stare molto attento a evitare la ricorsione infinita. Qualsiasi inizializzazione specifica della classe dovrebbe essere in '__init__', quindi penso che sia abbastanza sicuro qui presumere che l'unico lavoro di' __new__' è quello di creare un oggetto del tipo corretto. – Duncan