Python 多重继承:调用哪个 __new__?
我有一个叫做 Parent
的类。我想为这个类定义一个 __new__
方法,这样在创建实例的时候可以做一些特别的事情(具体原因可以看脚注)。我还希望子类能够继承这个类的特性,以及其他类也能获得 Parent
的功能。Parent
的 __new__
方法会返回一个子类的实例,这个子类是基于子类的父类和 Parent
类的。
这是子类的定义方式:
class Child(Parent, list):
pass
但是现在我不知道在 Parent
的 __new__
方法中应该调用哪个 __new__
。如果我调用 object.__new__
,上面的 Child
示例就会报错,提示应该调用 list.__new__
。可是 Parent
怎么会知道呢?我让它循环遍历所有的 __bases__
,并在 try:
块中调用每个 __new__
:
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)
但这看起来就像是一种变通的方法。肯定有更好的办法来做到这一点吧?
谢谢。
- 我想使用
__new__
的原因是,我希望返回一个具有一些动态属性的子类对象(比如神奇的__int__
属性等)分配给这个类。我 本可以在__init__
中做到这一点,但如果新类有不同的内部结构,我就无法在__init__
中修改self.__class__
,而这里正是因为多重继承导致了这种情况。
1 个回答
4
我觉得这样做可以满足你的需求:
return super(Parent, cls).__new__(cls, *args, **kwargs)
而且你不需要使用 bases
这个关键词参数。除非我理解错了,你是故意把它放进去的。