2015-02-08 81 views
1

的实例时__new__返回类的实例,一切都很好,我们没有任何问题创建子类:继承时__new __()不返回

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     return self 

    def __init__(self, p1, p2): 
     self.p1 = p1 
     self.p2 = p2 

class B(A): 
    def __new__(cls, p3): 
     self = super().__new__(cls, 1, 2) 
     return self 

    def __init__(self, p3): 
     super().__init__(1, 2) 
     self.p3 = p3 

a = A(1, 2)  
print(a.p2) # output: 2 

b = B(3) 
print(b.p3) # output: 3 

但是,

如果__new__()不会返回cls的实例,那么将不会调用新的 实例的__init__()方法。

看起来我们必须调用__init__()__new__()直接,但是这会导致错误,当我们在子类中调用super().__new__

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     self.__init__(p1, p2) # we should call __init__ directly 
     return [self] # return not instance 

    def __init__(self, p1, p2): 
     self.p1 = p1 
     self.p2 = p2 

class B(A): 
    def __new__(cls, p3): 
     self = super().__new__(cls, 1, 2) 
     return self 

    def __init__(self, p3): 
     self.p3 = p3 

a = A(1, 2)  
print(a[0].p2) # output: 2 

b = B(3) # TypeError: __init__() takes 2 positional arguments but 3 were given 
print(b[0].p3) 

如何解决呢?如果A.__new__()没有返回类的实例,如何创建A的子类?

回答

1

如果你要手动调用它,要么不命名方法__init__并使用每个类的名称,而不是,手动调用__init__方法绑定,直接在类。在类

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     self.__init(p1, p2) # call custom __init directly 
     return [self] # return not instance 

    def __init(self, p1, p2): 
     self.p1 = p1 
     self.p2 = p2 

class B(A): 
    def __new__(cls, p3): 
     self = super().__new__(cls, 1, 2) 
     self[0].__init(p3) # custom init 
     return self 

    def __init(self, p3): 
     self.p3 = p3 

或直接:

每类名是比较容易的,你可以在开始使用双下划线通过name mangling产生特异性类名

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     A.__init__(self, p1, p2) # call custom __init__ unbound 
     return [self] # return not instance 

    def __init__(self, p1, p2): 
     self.p1 = p1 
     self.p2 = p2 

class B(A): 
    def __new__(cls, p3): 
     self = super().__new__(cls, 1, 2) 
     B.__init__(self[0], p3) # call custom __init__ unbound 
     return self 

    def __init__(self, p3): 
     self.p3 = p3 

如果你这样做,你也可以用去掉带有一个自定义的初始化程序,只需要在__new__中完成初始化:

class A: 
    def __new__(cls, p1, p2): 
     self = object.__new__(cls) 
     self.p1 = p1 
     self.p2 = p2 
     return [self] # return not instance 


class B(A): 
    def __new__(cls, p3): 
     self = super().__new__(cls, 1, 2) 
     self[0].p3 = p3 
     return self 

毕竟,你已经有机会获得在创建时的情况下,你可能也初始化它那里,然后。