Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #64442 > unrolled thread
| Started by | Mû <mu--@melix.net> |
|---|---|
| First post | 2014-01-21 20:11 +0100 |
| Last post | 2014-01-21 11:20 -0800 |
| Articles | 7 — 5 participants |
Back to article view | Back to comp.lang.python
Modifying the default argument of function Mû <mu--@melix.net> - 2014-01-21 20:11 +0100
Re: Modifying the default argument of function Chris Angelico <rosuav@gmail.com> - 2014-01-22 06:19 +1100
Re: Modifying the default argument of function Mû <mu--@melix.net> - 2014-01-21 20:36 +0100
Re: Modifying the default argument of function Chris Angelico <rosuav@gmail.com> - 2014-01-22 06:46 +1100
Re: Modifying the default argument of function Asaf Las <roegltd@gmail.com> - 2014-01-21 16:30 -0800
Re: Modifying the default argument of function Steve Jones <steve@secretvolcanobase.org> - 2014-01-21 19:19 +0000
Re: Modifying the default argument of function emile <emile@fenx.com> - 2014-01-21 11:20 -0800
| From | Mû <mu--@melix.net> |
|---|---|
| Date | 2014-01-21 20:11 +0100 |
| Subject | Modifying the default argument of function |
| Message-ID | <52dec646$0$2934$426a74cc@news.free.fr> |
Hi everybody,
A friend of mine asked me a question about the following code:
[code]
def f(x=[2,3]):
x.append(1)
return x
print(f())
print(f())
print(f())
[/code]
The results are [2, 3, 1], [2, 3, 1, 1] and [2, 3, 1, 1, 1].
The function acts as if there were a global variable x, but the call of
x results in an error (undefined variable). I don't understand why the
successive calls of f() don't return the same value: indeed, I thought
that [2,3] was the default argument of the function f, thus I expected
the three calls of f() to be exactly equivalent.
I'm don't know much about python, does anybody have a simple explanation
please?
--
Mû
---
Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active.
http://www.avast.com
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-01-22 06:19 +1100 |
| Message-ID | <mailman.5813.1390331956.18130.python-list@python.org> |
| In reply to | #64442 |
On Wed, Jan 22, 2014 at 6:11 AM, Mû <mu--@melix.net> wrote:
> The function acts as if there were a global variable x, but the call of x
> results in an error (undefined variable). I don't understand why the
> successive calls of f() don't return the same value: indeed, I thought that
> [2,3] was the default argument of the function f, thus I expected the three
> calls of f() to be exactly equivalent.
In a sense, there is. The default for the argument is simply an object
like any other, and it's stored in one place.
For cases where you want a mutable default that is "reset" every time,
the most common idiom is this:
def f(x=None):
if x is None: x=[2,3]
x.append(1)
return x
That will create a new list every time, with the same initial contents.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Mû <mu--@melix.net> |
|---|---|
| Date | 2014-01-21 20:36 +0100 |
| Message-ID | <52decc31$0$2244$426a74cc@news.free.fr> |
| In reply to | #64444 |
Le 21/01/2014 20:19, Chris Angelico a écrit : > On Wed, Jan 22, 2014 at 6:11 AM, Mû <mu--@melix.net> wrote: >> The function acts as if there were a global variable x, but the call of x >> results in an error (undefined variable). I don't understand why the >> successive calls of f() don't return the same value: indeed, I thought that >> [2,3] was the default argument of the function f, thus I expected the three >> calls of f() to be exactly equivalent. > > In a sense, there is. The default for the argument is simply an object > like any other, and it's stored in one place. > > For cases where you want a mutable default that is "reset" every time, > the most common idiom is this: > > def f(x=None): > if x is None: x=[2,3] > x.append(1) > return x > > That will create a new list every time, with the same initial contents. > > ChrisA > Thank you, thanks everybody, These were clear and quick answers to my problem. I did not think of this possibility: the default argument is created once, but accessible only by the function, therefore is not a global variable, whereas it looks like if it were at first glance. -- Mû --- Ce courrier électronique ne contient aucun virus ou logiciel malveillant parce que la protection avast! Antivirus est active. http://www.avast.com
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-01-22 06:46 +1100 |
| Message-ID | <mailman.5816.1390333586.18130.python-list@python.org> |
| In reply to | #64448 |
On Wed, Jan 22, 2014 at 6:36 AM, Mû <mu--@melix.net> wrote:
> These were clear and quick answers to my problem. I did not think of this
> possibility: the default argument is created once, but accessible only by
> the function, therefore is not a global variable, whereas it looks like if
> it were at first glance.
You can actually poke at the function a bit and see what's happening.
Try this in the interactive interpreter:
>>> def f(x=[2,3]):
x.append(1)
return x
>>> f()
[2, 3, 1]
>>> f()
[2, 3, 1, 1]
>>> f.__defaults__
([2, 3, 1, 1],)
The __defaults__ attribute of a function is a tuple of its parameter
defaults. You can easily see there that the list has changed as you
changed it in the function. You could check it with id() or is, too:
>>> id(f.__defaults__[0])
24529576
>>> id(f())
24529576
>>> f() is f.__defaults__[0]
True
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Asaf Las <roegltd@gmail.com> |
|---|---|
| Date | 2014-01-21 16:30 -0800 |
| Message-ID | <5e78b144-5e3d-48c2-adb1-df64878b8bf2@googlegroups.com> |
| In reply to | #64449 |
On Tuesday, January 21, 2014 9:46:16 PM UTC+2, Chris Angelico wrote:
> On Wed, Jan 22, 2014 at 6:36 AM, Mû <mu--@melix.net> wrote:
> > These were clear and quick answers to my problem. I did not think of this
> > possibility: the default argument is created once, but accessible only by
> > the function, therefore is not a global variable, whereas it looks like if
> > it were at first glance.
> You can actually poke at the function a bit and see what's happening.
> Try this in the interactive interpreter:
> >>> def f(x=[2,3]):
> x.append(1)
> return x
> >>> f()
> [2, 3, 1]
> >>> f()
> [2, 3, 1, 1]
> >>> f.__defaults__
> ([2, 3, 1, 1],)
>
> The __defaults__ attribute of a function is a tuple of its parameter
> defaults. You can easily see there that the list has changed as you
> changed it in the function. You could check it with id() or is, too:
> >>> id(f.__defaults__[0])
> 24529576
> >>> id(f())
> 24529576
> >>> f() is f.__defaults__[0]
> True
> ChrisA
that reminds me C's static :-)
def func(y, x = [1]):
if y != 1 :
func.__defaults__[0][0] = y
print(func.__defaults__[0])
func(0)
func(2)
func(1)
[0]
[2]
[2]
p.s. Mu, thanks for question!
[toc] | [prev] | [next] | [standalone]
| From | Steve Jones <steve@secretvolcanobase.org> |
|---|---|
| Date | 2014-01-21 19:19 +0000 |
| Message-ID | <20140121191953.6c8dae28@steves-laptop> |
| In reply to | #64442 |
On Tue, 21 Jan 2014 20:11:02 +0100 Mû <mu--@melix.net> wrote: > Hi everybody, > > A friend of mine asked me a question about the following code: > > [code] > def f(x=[2,3]): > x.append(1) > return x > > print(f()) > print(f()) > print(f()) > [/code] > > The results are [2, 3, 1], [2, 3, 1, 1] and [2, 3, 1, 1, 1]. > > The function acts as if there were a global variable x, but the call of > x results in an error (undefined variable). I don't understand why the > successive calls of f() don't return the same value: indeed, I thought > that [2,3] was the default argument of the function f, thus I expected > the three calls of f() to be exactly equivalent. > > I'm don't know much about python, does anybody have a simple explanation > please? x is assigned to the list [2, 3] at the time the function is created not when the function is called, meaning that there's only ever 1 list created. When you call x.append this list is modified and the next time the function is called x still refers to this modified list.
[toc] | [prev] | [next] | [standalone]
| From | emile <emile@fenx.com> |
|---|---|
| Date | 2014-01-21 11:20 -0800 |
| Message-ID | <mailman.5814.1390332031.18130.python-list@python.org> |
| In reply to | #64442 |
Function defs with mutable arguments hold a reference to the mutable container such that all invocations access the same changeable container. To get separate mutable default arguments, use: def f(x=None): if x is None: x=[2,3] Emile On 01/21/2014 11:11 AM, Mû wrote: > Hi everybody, > > A friend of mine asked me a question about the following code: > > [code] > def f(x=[2,3]): > x.append(1) > return x > > print(f()) > print(f()) > print(f()) > [/code] > > The results are [2, 3, 1], [2, 3, 1, 1] and [2, 3, 1, 1, 1]. > > The function acts as if there were a global variable x, but the call of > x results in an error (undefined variable). I don't understand why the > successive calls of f() don't return the same value: indeed, I thought > that [2,3] was the default argument of the function f, thus I expected > the three calls of f() to be exactly equivalent. > > I'm don't know much about python, does anybody have a simple explanation > please? >
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web