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 in self.__class__ __init__ se la nuova classe ha una diversa struttura interna, che è il caso qui a causa di ereditarietà multipla.
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top