__new__永远不会在替代课程上运行

时间:2017-11-07 08:50:20

标签: python class

我在调用__new__方法时遇到了困难。

创建A()的实例时,如果输入低于10,我想返回B()的实例。但实例是在不运行__new__或{{1}的情况下创建的* } __init__的方法,为什么会这样?

B

此输出

class A (object):
    def __init__ (self, IP, s):
        print 'arrived to init a'
        self.IP=IP
        print self.IP
        print s
    def __new__ (cls, IP, s):
        print "arrived to new a"
        if IP>10:
            self = object.__new__ (cls)
            return self  # return n
        else:
            return super (cls, A).__new__ (B)

class B(object):
    def __init__(self,d,s,ar):
        print 'arrived to b'
        self.ip=d
        print self.ip
        print s
        print ar
    def __new__(cls,d,s,ar):
        print 'arrived to new b' 
        self = object.__new__(cls)
        return self  # return n
    def __repr__(self):
        return 'B({}, ..., ...)'.format(getattr(self, 'ip', '<missing>'))

a = A(10 ,"a")
print a

而不是

arrived to new a
B(<missing>, ..., ...)

1 个答案:

答案 0 :(得分:1)

您要求object.__new__在此处创建新实例:

return super (cls, A).__new__ (B)

所以A.__new__在这里返回B()的实例,而因为这会返回一个新的B()实例,而不是新的A()实例,B.__init__()永远不会被召唤;类型需要匹配。请参阅object.__new__ documentation

  

如果__new__()返回cls的实例,则会调用新实例的__init__()方法,如__init__(self[, ...]),其中self是新实例,其余参数与传递给__new__()的参数相同。

B()不是A的实例,因此不会调用__init__B.__new__未被调用,因为您通过要求object.__new__代替创建实例来明确绕过它。

只需在B()中直接致电A.__new__

    if IP>10:
        self = object.__new__ (cls)
        return self  # return n
    else:
        return B(IP, s, 42)

你需要传入三个参数;我为第三个人制作了42

由于调用了B(),因此将调用B.__new__。由于B.__new__会返回B的实例,因此也会调用__init__方法。

演示:

>>> A(10 ,"a")
arrived to new a
arrived to new b
arrived to b
10
a
42
B(10, ..., ...)