__new__

1 view
Skip to first unread message

James Stroud

unread,
Nov 6, 2005, 1:45:37 AM11/6/05
to pytho...@python.org
Hello All,

I'm running 2.3.4

I was reading the documentation for classes & types
http://www.python.org/2.2.3/descrintro.html
And stumbled on this paragraph:

"""
__new__ must return an object. There's nothing that requires that it return a
new object that is an instance of its class argument, although that is the
convention. If you return an existing object, the constructor call will still
call its __init__ method. If you return an object of a different class, its
__init__ method will be called.
"""

The quote implies that when I call carol, b.__init__ should be called.
However, this does not seem to be the case (see code below). What am I not
understanding? Shouldn't the interpreter call b.__init__ when b is returned
from carol.__new__?

James

py> class bob(object):
... def __init__(self):
... print self.x
... x = 2
...
py> class carol(object):
... def __new__(cls):
... return b
...
py> b=bob()
py> b.x
2
py> c = carol() # should print "2"
py> c
<__main__.bob object at 0x404333cc>

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/

EP

unread,
Nov 6, 2005, 2:02:21 AM11/6/05
to James Stroud, pytho...@python.org
James Stroud <wrote:

> The quote implies that when I call carol, b.__init__ should be called.
> However, this does not seem to be the case (see code below). What am I
> not
> understanding? Shouldn't the interpreter call b.__init__ when b is
> returned
> from carol.__new__?
>
> James
>
> py> class bob(object):
> ... def __init__(self):
> ... print self.x
> ... x = 2
> ...
> py> class carol(object):
> ... def __new__(cls):
> ... return b
> ...
> py> b=bob()
> py> b.x
> 2
> py> c = carol() # should print "2"
> py> c
> <__main__.bob object at 0x404333cc>
>


It seems to produce the output you expected for me (Python 2.4.1 on Windows XP), but this has nothing to do with "carol". How are bob and carol related?

Code:

class bob(object):
def __init__(self):
print self.x
x = 2

class carol(object):
def __new__(cls):
return b
b=bob()
print b.x
c = carol()
c

Output:

>>>
2
2


This code produces the same output:

class bob(object):
def __init__(self):
print self.x
x = 2
## class carol(object):
## def __new__(cls):
## return b
b=bob()
print b.x
## c = carol()
##c


I am interested in the underlying subject but think your code was mispasted into the e-mail...

Peter Otten

unread,
Nov 6, 2005, 5:03:18 AM11/6/05
to
James Stroud wrote:

> I'm running 2.3.4
>
> I was reading the documentation for classes & types
> http://www.python.org/2.2.3/descrintro.html
> And stumbled on this paragraph:
>
> """
> __new__ must return an object. There's nothing that requires that it
> return a new object that is an instance of its class argument, although
> that is the convention. If you return an existing object, the constructor
> call will still call its __init__ method. If you return an object of a
> different class, its __init__ method will be called.
> """
>
> The quote implies that when I call carol, b.__init__ should be called.
> However, this does not seem to be the case (see code below). What am I not
> understanding? Shouldn't the interpreter call b.__init__ when b is
> returned from carol.__new__?

Here's what "Python in a Nutshell" (p84) says:

"""
Each new-style class has a static method named __new__. When you call
C(*args, **kwds) to create a new instance of a new-style class C, Python
invokes C.__new__(C, *args, **kwds). Python uses __new__'s return value x
as the newly created instance. Then, Python calls C.__init__(x, *args,
**kwds), but only when x is indeed an instance of C (otherwise, x's state
is as __new__ had left it). Thus, for a new-style class C, the statement
x=C(23) is equivlent to the following code:

x = C.__new__(C, 23)
if isinstance(x, C): C.__init__(x, 23)
"""

If the following code says what I think it does

class A(object):
def __init__(self):
print "init A"
def __new__(cls):
return b


class B(A):
def __init__(self):
print "init B"


b = object.__new__(B)

print "---"
A() # prints 'init B'
A.__init__(b) # prints 'init A'
print "---"
b = 42
A() # prints nothing

the "Nutshell" example should be changed to

x = C.__new__(C, 23)
if isinstance(x, C): x.__init__(23)

to comply with the current implementation (I used Python 2.4).

Peter

Alex Martelli

unread,
Nov 6, 2005, 11:12:19 AM11/6/05
to
Peter Otten <__pet...@web.de> wrote:
...

> is as __new__ had left it). Thus, for a new-style class C, the statement
> x=C(23) is equivlent to the following code:
>
> x = C.__new__(C, 23)
> if isinstance(x, C): C.__init__(x, 23)
...

> the "Nutshell" example should be changed to
>
> x = C.__new__(C, 23)
> if isinstance(x, C): x.__init__(23)
>
> to comply with the current implementation (I used Python 2.4).

Hmmm -- not quite, because in the new-style object model special methods
are taken from the type, NOT from the instance as the latter is saying.
E.g, if you change class B into:

class B(A):
def __init__(self):
print "init B"

def f(): print 'from instance'
self.__init__ = f

you'll see that while b.__init__() would print 'from instance',
instantiating A will not. I think the right correction to the Nutshell
is therefore:

x = C.__new__(C, 23)
if isinstance(x, C): type(x).__init__(x, 23)

and this is how I plan to have it in the 2nd edition.


Alex

Steven Bethard

unread,
Nov 8, 2005, 2:57:37 PM11/8/05
to
James Stroud wrote:
> Hello All,
>
> I'm running 2.3.4
>
> I was reading the documentation for classes & types
> http://www.python.org/2.2.3/descrintro.html
> And stumbled on this paragraph:
>
> """
> __new__ must return an object. There's nothing that requires that it return a
> new object that is an instance of its class argument, although that is the
> convention. If you return an existing object, the constructor call will still
> call its __init__ method. If you return an object of a different class, its
> __init__ method will be called.
> """

Any reason why you're looking at 2.2 documentation when you're running 2.3?

Anyway, the current docs corrected this mistake[1]

"""
If __new__() returns an instance of cls, then the new instance's
__init__() method will be invoked like "__init__(self[, ...])", where
self is the new instance and the remaining arguments are the same as
were passed to __new__().

If __new__() does not return an instance of cls, then the new instance's
__init__() method will not be invoked.
"""

[1]http://docs.python.org/ref/customization.html

STeVe

Reply all
Reply to author
Forward
0 new messages