Python ereditarietà multipla: che __new__ chiamare?
-
22-09-2019 - |
Domanda
Ho un Parent
di classe. Voglio definire un __new__
per Parent
così fa qualche magia su di istanze (per il motivo per cui, vedi nota in calce). Voglio anche corsi per bambini di ereditare da questa e altre classi per ottenere le caratteristiche della Capogruppo. Parent
del __new__
restituirebbe un'istanza di una sottoclasse di basi della classe bambino e la classe Parent
.
Questa è come la classe bambino sarebbe definito:
class Child(Parent, list):
pass
Ma ora io non so cosa __new__
chiamare Parent
di __new__
. Se chiamo object.__new__
, l'esempio sopra Child
lamenta che list.__new__
dovrebbe essere chiamato. Ma come sarebbe Parent
sapere che? Ho fatto funzionare in modo che scorre tutte le __bases__
, e chiamare ogni __new__
all'interno di un blocco try:
:
class Parent(object):
def __new__(cls, *args, **kwargs):
# There is a special wrapper function for instantiating instances of children
# classes that passes in a 'bases' argument, which is the __bases__ of the
# Children class.
bases = kwargs.get('bases')
if bases:
cls = type('name', bases + (cls,), kwargs.get('attr', {}))
for base in cls.__mro__:
if base not in (cls, MyMainType):
try:
obj = base.__new__(cls)
break
except TypeError:
pass
return obj
return object.__new__(cls)
Ma questo sembra proprio come un hack. Sicuramente, ci deve essere un modo migliore di fare questo?
Grazie.
- Il motivo che voglio usare
__new__
è così posso restituire un oggetto di una sottoclasse che ha alcuni attributi dinamici (attributi__int__
magia, ecc) assegnati alla classe. I avrebbe potuto fare questo a__init__
, ma non sarebbe in grado di modificare inself.__class__
__init__
se la nuova classe ha una diversa struttura interna, che è il caso qui a causa di ereditarietà multipla.
Soluzione
Credo che questo ti porterà ciò che si vuole:
return super(Parent, cls).__new__(cls, *args, **kwargs)
e non sarà necessario l'argomento bases
parola chiave. A meno che non mi sto voi sbagliato e si è messa che lì apposta.