Python multiple inheritance: which __new__ to call?

I have a Parent class. I want to define __new__ for Parent so that it does some magic when instantiating (for why, see Footnote). I also want the child classes to inherit this and other classes in order to get the Parent functions. Parent __new__ will return an instance of a subclass of the base classes and the Parent class.

Here's how the child class will be defined:

 class Child(Parent, list): pass 

But now I do not know what __new__ to call Parent __new__ . If I call object.__new__ , the above example Child complains that list.__new__ should be called. But how would you know? I made it work so that it goes through all __bases__ and __new__ each __new__ inside the 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.__mro__: if base not in (cls, MyMainType): try: obj = base.__new__(cls) break except TypeError: pass return obj return object.__new__(cls) 

But it just looks like a hack. Surely there should be a better way to do this?

Thanks.

  • The reason I want to use __new__ is because I can return a subclass object that has some dynamic attributes (magic attributes __int__ , etc.) assigned to the class. I could do this in __init__ , but I could not change self.__class__ to __init__ if the new class has a different internal structure, which is due to multiple inheritance here.
+4
source share
1 answer

I think this will give you what you want:

 return super(Parent, cls).__new__(cls, *args, **kwargs) 

and you don’t need the bases keyword argument. If I'm not mistaken, and you intentionally do it there.

+4
source

Source: https://habr.com/ru/post/1299396/


All Articles