__init__ vs __new__

D

Daniel Klein

I've have a program that is using both of the methods below (in
different classes of course) for initializing the class. The example
below shows a class with the 2 methods with one commented out.

class JsubroutineParameters(list):
"Represents a list of arguments for external subroutine calls."
# We only need to override methods which add objects to the list.

def __init__(self, alist = []):
for objekt in alist: _validateParameter(objekt)
self.extend(alist)

#def __new__(cls, alist = []):
# for objekt in alist: _validateParameter(objekt)
# return list.__new__(cls, alist)

I don't really notice any behavioral difference. Is there in fact any
difference in using one over the other? Performance? Side effects? ???

I am using Python version 2.5.

Thanks,
Daniel Klein
 
N

Neil Cerutti

I've have a program that is using both of the methods below (in
different classes of course) for initializing the class. The
example below shows a class with the 2 methods with one
commented out.

class JsubroutineParameters(list):
"Represents a list of arguments for external subroutine calls."
# We only need to override methods which add objects to the list.

def __init__(self, alist = []):
for objekt in alist: _validateParameter(objekt)
self.extend(alist)

#def __new__(cls, alist = []):
# for objekt in alist: _validateParameter(objekt)
# return list.__new__(cls, alist)

I don't really notice any behavioral difference. Is there in
fact any difference in using one over the other? Performance?
Side effects? ???

I am using Python version 2.5.

The second version doesn't work the way you might be assuming.

Guido's paper says that mutable builtins like list have a dummy
__new__ static method. So 'return list.__new__(cls, alist)' does
nothing. It seems to work because the base class __init__
performs the initialization (assuming your __init__ above is
commented out). You can see this by providing a dummy __init__.

class Example(list):
def __new__(cls, alist):
return list.__new__(cls, alist)
def __init__(self, alist):
pass
[]

There is no need to use __new__ for mutable builtin types. Since
all you want from this construction is a side-effect, you can
nevertheless use it in this case.

Your __init__ should call the base-class __init__.

It's usually a bad idea to provide mutable types as default
arguments. Since you aren't modifying alist in __init__ you can
get away with it here, but getting in the habit of using the
below idiom might save you from a "gotcha" someday.

class JsubroutineParameters(list):
def __init__(self, alist=None):
if alist is None:
alist = []
for objekt in alist: _validateParameter(objekt)
list.__init__(self, alist)

You will no longer need to call append.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top