Python多重继承:动态做错了什么?

时间:2010-01-08 09:27:08

标签: python multiple-inheritance

基于this answer__new____init__应该如何在Python中运行,

我编写了这段代码来动态定义和创建一个新的类和对象。

class A(object):
    def __new__(cls):
      class C(cls, B):
          pass
      self = C()
      return self

    def foo(self):
      print 'foo'

class B(object):
    def bar(self):
      print 'bar'

a = A()
a.foo()
a.bar()

基本上,因为A的__new__返回一个继承A和B的动态创建的C,它应该有一个属性bar

为什么C 具有bar属性?

3 个答案:

答案 0 :(得分:7)

由于问题中没有实际的问题,我将从字面上理解:

动态做错了什么?
嗯,对于你的代码的用户来说,它实际上是不可读的,非常不透明和不明显的(包括你在一个月内:P)。

根据我的经验(非常有限,我必须承认,不幸的是,我没有20年的编程),对此类解决方案的需求表明,类结构没有明确定义, - 意味着,差不多总是一个更好,更可读,更不神秘的方式来做这些事情。

例如,如果真的想要动态定义基类,最好使用工厂函数,它将根据您的需要返回适当的类。

另一个问题:
动态做错了什么?
在您当前的实现中,它给出了“超出最大递归深度”错误。发生这种情况,因为A.__new__无限期地从内部调用自身(因为它从自身和B继承)。

10:A.__new__内,“cls”设置为<class '.A'>。在构造函数中,您定义了一个类C,它继承自cls(实际上是A)和另一个类B。实例化C后,将调用其__new__。由于它没有定义自己的__new__,因此调用其基类“__new__。基类恰好是A 20:GOTO 10

答案 1 :(得分:7)

Resolve无限递归:

class A(object):
  def __new__(cls):
    class C(cls, B):
      pass
    self = object.__new__(C)
    return self

(感谢balpha指出实际问题。)

答案 2 :(得分:3)

如果你的问题是“我怎样才能做到这一点” - 这有效:

class A(object):
    @classmethod
    def get_with_B(cls):
      class C(B, cls):
        pass

      return C()

    def foo(self):
      print 'foo'

class B(object):
    def bar(self):
      print 'bar'

a = A.get_with_B()
a.foo()
a.bar()

如果您的问题是“为什么它不起作用” - 那是因为当您致电C()时会遇到无限递归,这导致A.__new__被调用,再次调用{{1}等等。