Reputation: 211
I am having difficulties with invoking the __new__
method.
When creating an instance of A(), I want to return an instance of B()
instead if the input below 10. But the instance is created *without running the __new__
or __init__
methods of B
, why is that?
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
This outputs
arrived to new a
B(<missing>, ..., ...)
instead of
arrived to new a
arrived to new b
arrived to b
10
'a'
?
B(10, ..., ...)
Upvotes: 0
Views: 60
Reputation: 1121654
You are asking object.__new__
to create a new instance here:
return super (cls, A).__new__ (B)
So A.__new__
returns an instance of B()
here, and because this returns a new B()
instance, and not a new A()
instance, B.__init__()
will never be called; the types need to match. See the object.__new__
documentation:
If
__new__()
returns an instance ofcls
, then the new instance’s__init__()
method will be invoked like__init__(self[, ...])
, whereself
is the new instance and the remaining arguments are the same as were passed to__new__()
.
B()
is not an instance of A
so __init__
is not called. B.__new__
is not called because you explicitly bypassed it by asking object.__new__
to create the instance instead.
Just call B()
directly in your A.__new__
:
if IP>10:
self = object.__new__ (cls)
return self # return n
else:
return B(IP, s, 42)
You need to pass in three arguments; I made up 42
for the third.
Because B()
is called, B.__new__
will be called. Because B.__new__
returns an instance of B
, the __init__
method will also be called.
Demo:
>>> A(10 ,"a")
arrived to new a
arrived to new b
arrived to b
10
a
42
B(10, ..., ...)
Upvotes: 1