Default argument to __init__

N

netvaibhav

Hi All:

Here's a piece of Python code and it's output. The output that Python
shows is not as per my expectation. Hope someone can explain to me this
behaviour:

Code:
class MyClass:
        def __init__(self, myarr=[]):
                self.myarr = myarr

myobj1 = MyClass()
myobj2 = MyClass()

myobj1.myarr += [1,2,3]

myobj2.myarr += [4,5,6]

print myobj1.myarr
print myobj2.myarr

The output is:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]

Why do myobj1.myarr and myobj2.myarr point to the same list? The
default value to __init__ for the myarr argument is [], so I expect
that every time an object of MyClass is created, a new empty list is
created and assigned to myarr, but it seems that the same empty list
object is assigned to myarr on every invocation of MyClass.__init__

It this behaviour by design? If so, what is the reason, as the
behaviour I expect seems pretty logical.

Thanks.

Vaibhav
 
S

Steve Holden

Hi All:

Here's a piece of Python code and it's output. The output that Python
shows is not as per my expectation. Hope someone can explain to me this
behaviour:

Code:
class MyClass:
def __init__(self, myarr=[]):
self.myarr = myarr

myobj1 = MyClass()
myobj2 = MyClass()

myobj1.myarr += [1,2,3]

myobj2.myarr += [4,5,6]

print myobj1.myarr
print myobj2.myarr

The output is:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]

Why do myobj1.myarr and myobj2.myarr point to the same list? The
default value to __init__ for the myarr argument is [], so I expect
that every time an object of MyClass is created, a new empty list is
created and assigned to myarr, but it seems that the same empty list
object is assigned to myarr on every invocation of MyClass.__init__

It this behaviour by design? If so, what is the reason, as the
behaviour I expect seems pretty logical.
The default value of the keyword argument is evaluated once, at function
declaration time. The idiom usually used to avoid this gotcha is:

def __init__(self, myarr=None):
if myarr is None:
myarr = []

This ensures each call with the default myarr gets its own list.

regards
Steve
 
S

skip

vaibhav> Here's a piece of Python code and it's output. The output that
vaibhav> Python shows is not as per my expectation. Hope someone can
vaibhav> explain to me this behaviour:
...


Yes, your default arg is evaluated once, at method definition time and
shared betwee all instances of MyClass. See the thread last week on the
same thing for more detail.

Skip
 
F

Fredrik Lundh

Here's a piece of Python code and it's output. The output that Python
shows is not as per my expectation. Hope someone can explain to me this
behaviour:

/snip/
Why do myobj1.myarr and myobj2.myarr point to the same list? The
default value to __init__ for the myarr argument is [], so I expect
that every time an object of MyClass is created, a new empty list is
created and assigned to myarr, but it seems that the same empty list
object is assigned to myarr on every invocation of MyClass.__init__

It this behaviour by design?

it's explained in the FAQ:

http://www.python.org/doc/faq/general.html#why-are-default-values-shared-between-objects

it's also mentioned in chapter 4 of the tutorial:

http://docs.python.org/tut/node6.html#SECTION006710000000000000000

"*Important warning*: The default value is evaluated only once. This
makes a difference when the default is a mutable object such as a list,
dictionary, or instances of most classes. "

(the text then illustrates this with examples, and shows how to do things
instead)

and in the description of "def" in the language reference:

http://docs.python.org/ref/function.html

"*Default parameter values are evaluated when the function definition
is executed*. This means that the expression is evaluated once, when the
function is defined, and that that same "pre-computed" value is used for
each call. This is especially important to understand when a default para-
meter is a mutable object, such as a list or a dictionary: if the function
modifies the object (e.g. by appending an item to a list), the default
value is in effect modified."

(the text then shows how to do things instead)
If so, what is the reason, as the behaviour I expect seems pretty logical.

that only means that you don't fully understand what "def" does (hint: it's
a statement, not a compiler directive).

</F>
 
D

Dennis Lee Bieber

Hi All:

Here's a piece of Python code and it's output. The output that Python
shows is not as per my expectation. Hope someone can explain to me this
behaviour:

Code:
class MyClass:
def __init__(self, myarr=[]):
self.myarr = myarr[/QUOTE]

	Python Reference Manual section 7.5 (on my install at least)

"""
Default parameter values are evaluated when the function definition is
executed. This means that the expression is evaluated once, when the
function is defined, and that that same ``pre-computed'' value is used
for each call. This is especially important to understand when a default
parameter is a mutable object, such as a list or a dictionary: if the
function modifies the object (e.g. by appending an item to a list), the
default value is in effect modified. This is generally not what was
intended. A way around this is to use None as the default, and
explicitly test for it in the body of the function, e.g.: 

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin
"""
--
 

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,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top