__init__ vs __new__
horpner at yahoo.com
Thu Jan 11 16:33:51 CET 2007
On 2007-01-11, Daniel Klein <danielkleinad at gmail.com> wrote:
> 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)
> #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__.
def __new__(cls, alist):
return list.__new__(cls, alist)
def __init__(self, alist):
>>> a = Example(range(5))
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.
def __init__(self, alist=None):
if alist is None:
alist = 
for objekt in alist: _validateParameter(objekt)
You will no longer need to call append.
More information about the Python-list