__init__ vs __new__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Daniel Klein

    #1

    __init__ vs __new__

    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 JsubroutinePara meters(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: _validateParame ter(objekt)
    self.extend(ali st)

    #def __new__(cls, alist = []):
    # for objekt in alist: _validateParame ter(objekt)
    # return list.__new__(cl s, 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
  • Neil Cerutti

    #2
    Re: __init__ vs __new__

    On 2007-01-11, Daniel Klein <danielkleinad@ gmail.comwrote:
    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 JsubroutinePara meters(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: _validateParame ter(objekt)
    self.extend(ali st)
    >
    #def __new__(cls, alist = []):
    # for objekt in alist: _validateParame ter(objekt)
    # return list.__new__(cl s, 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__(cl s, 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__(cl s, alist)
    def __init__(self, alist):
    pass
    >>a = Example(range(5 ))
    >>a
    []

    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 JsubroutinePara meters(list):
    def __init__(self, alist=None):
    if alist is None:
    alist = []
    for objekt in alist: _validateParame ter(objekt)
    list.__init__(s elf, alist)

    You will no longer need to call append.

    --
    Neil Cerutti

    Comment

    Working...