Python multiple inheritance: which __new__ to call?
I have a class Parent
. I want to define a __new__
for Parent
so it does some magic upon instantiation (for why, see footnote). I also want children classes to inherit from this and other classes to get Parent's features. The Parent
's __new__
would return an instance of a subclass of the child class's bases and the Parent
class.
This is how the child class would be defined:
class Child(Parent, list):
pass
But now I don't know what __new__
to call in Parent
's __new__
. If I call object.__new__
, the above Child
example complains that list.__new__
should be called. But how would Parent
know that? I made it work so it loops through all the __bases__
, and call each __new__
inside a try:
block:
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开发者_Go百科.__mro__:
if base not in (cls, MyMainType):
try:
obj = base.__new__(cls)
break
except TypeError:
pass
return obj
return object.__new__(cls)
But this just looks like a hack. Surely, there must be a better way of doing this?
Thanks.
- The reason I want to use
__new__
is so I can return an object of a subclass that has some dynamic attributes (the magic__int__
attributes, etc) assigned to the class. I could have done this in__init__
, but I would not be able to modifyself.__class__
in__init__
if the new class has a different internal structure, which is the case here due to multiple inheritance.
I think this will get you what you want:
return super(Parent, cls).__new__(cls, *args, **kwargs)
and you won't need the bases
keyword argument. Unless I'm getting you wrong and you're putting that in there on purpose.
精彩评论