在Python中,如何避免在__new __中使用super()派生的类中调用__init__两次:

时间:2016-05-24 02:17:59

标签: python super derived-class

我是python的新手。不知何故

__init__
对于使用

从另一个类派生的类,

被调用两次

super()

我的问题是如何避免这种情况,因为我的计算非常昂贵。

class A(object):
  def __new__(cls, *args, **kwargs):
    print("Class A: __new__")
    obj = super(A, cls).__new__(cls) # super is used here
    obj.__init__(*args, **kwargs)
    return obj
  def __init__(self, x):
    self.attrib = x+1

class B(A):
  def __init__(self, x):
    print("Class B: __init__")
    self.prop = 2*x # some expensive computation

a = A(10) # a test call

b = B(20) # Q: here, how to avoid calling __init__ twice in class B?

编辑: 谢谢你们的回答。我的真实代码是使用scipy库中内置的arpack对大型稀疏矩阵进行对角化。我正在调用在arpack.py中定义的类SpLuInv(LinearOperator),其中在Interface.py中定义了类LinearOperator,这两个文件都附加了:arpack.pyinterface.py。当我调用SpLuInv()时,它的 init 被调用两次。从你的答案,我想我需要删除在的LinearOperator()中的obj。 init

感谢Brendan Abel的回答以及Akshat Mahajan和Mike Graham的意见。除去

obj.__init__

来自

__new__

LinearOperator()

解决了这个问题。 :)

1 个答案:

答案 0 :(得分:4)

您不应该在__init__中手动呼叫__new__。从__new__返回的对象将自动调用__init__

所有你的课程中调用超类__init__,即使他们只是从object继承。

这是一个问题的唯一时间是 singleton 对象之类的东西,它通常从__init__返回已经__new__的对象。在这种情况下,您只需将类的实例存储为类属性,并在设置属性时直接从__init__返回。

class A(object):
    def __new__(cls, *args, **kwargs):
        print("Class A: __new__")
        obj = super(A, cls).__new__(cls) # super is used here
        return obj

    def __init__(self, x):
        super(A, self).__init__()
        self.attrib = x+1

class B(A):
    def __init__(self, x):
        print("Class B: __init__")
        super(B, self).__init__(x)
        self.prop = 2*x # some expensive computation