473,327 Members | 1,920 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Default argument to __init__

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:

Expand|Select|Wrap|Line Numbers
  1. class MyClass:
  2. def __init__(self, myarr=[]):
  3. self.myarr = myarr
  4.  
  5. myobj1 = MyClass()
  6. myobj2 = MyClass()
  7.  
  8. myobj1.myarr += [1,2,3]
  9.  
  10. myobj2.myarr += [4,5,6]
  11.  
  12. print myobj1.myarr
  13. print myobj2.myarr
  14.  
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

Oct 10 '05 #1
5 2289
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
Oct 10 '05 #2
This comes up on the list about once a week on this list.

See:
http://www.nexedi.org/sections/educa...mutable_n/view

-Larry Bates

ne********@gmail.com wrote:
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:

Expand|Select|Wrap|Line Numbers
  1.  class MyClass:
  2.          def __init__(self, myarr=[]):
  3.                  self.myarr = myarr
  4.  myobj1 = MyClass()
  5.  myobj2 = MyClass()
  6.  myobj1.myarr += [1,2,3]
  7.  myobj2.myarr += [4,5,6]
  8.  print myobj1.myarr
  9.  print myobj2.myarr
  10.  

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

Oct 10 '05 #3
ne********@gmail.com wrote:
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:

Expand|Select|Wrap|Line Numbers
  1.  class MyClass:
  2.          def __init__(self, myarr=[]):
  3.                  self.myarr = myarr
  4.  myobj1 = MyClass()
  5.  myobj2 = MyClass()
  6.  myobj1.myarr += [1,2,3]
  7.  myobj2.myarr += [4,5,6]
  8.  print myobj1.myarr
  9.  print myobj2.myarr
  10.  

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
--
Steve Holden +44 150 684 7255 +1 800 494 3119
Holden Web LLC www.holdenweb.com
PyCon TX 2006 www.python.org/pycon/

Oct 10 '05 #4
"ne********@gmail.com" wrote:
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/genera...etween-objects

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

http://docs.python.org/tut/node6.htm...00000000000000

"*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>

Oct 10 '05 #5
On 10 Oct 2005 07:50:12 -0700, ne********@gmail.com declaimed the
following in comp.lang.python:
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
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
"""
-- ================================================== ============ <
wl*****@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
wu******@dm.net | Bestiaria Support Staff <
================================================== ============ <
Home Page: <http://www.dm.net/~wulfraed/> <
Overflow Page: <http://wlfraed.home.netcom.com/> <

Oct 10 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

26
by: Alex Panayotopoulos | last post by:
Hello all, Maybe I'm being foolish, but I just don't understand why the following code behaves as it does: - = - = - = - class listHolder: def __init__( self, myList= ): self.myList =...
49
by: Mark Hahn | last post by:
As we are addressing the "warts" in Python to be fixed in Prothon, we have come upon the mutable default parameter problem. For those unfamiliar with the problem, it can be seen in this Prothon...
44
by: gregory.petrosyan | last post by:
Hello everybody! I have little problem: class A: def __init__(self, n): self.data = n def f(self, x = ????) print x All I want is to make self.data the default argument for self.f(). (I
43
by: kenneth | last post by:
Dear all, I have encountered this weird problem. I have a class definition with an __init__ argument 'd' which defaults to {}. This argument is put in the 'self.d' attribute at initialization...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.