F
Fred Ma
Hello,
I'm looking at Python for the 1st time today, motivated by its clarity
of syntax. I've looked at the tutoarial at
http://www.python.org/doc/current/tut/tut.html, particularly at the
section about default arguments. I've got some C++/STL under my belt,
so I'm familiar with passing/returning by reference, by value, and by
pointers. I've also used containers of pointers, as well as c++
default parameter values. I am aware of the general idea of reference
counting, but have never used it.
From the python tutorial, it's clear that to avoid sharing default
values between function calls, one has to avoid:
Example#1
---------
def f(a, L=[]):
L.append(a)
return L
Instead, one should use:
Example#2
---------
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
None has been described a analogous to the NULL value in c++. I'm
been looking and googling this newsgroup to get a clearer explanation
of why this works. The tutorial says that the default value is only
evaluated once. By that, I assume that there is some unnamed object
that is given the value of the 1st and only evaluation of the default
expression. Every time the function is called without an L parameter,
L gets the value of this unnamed object. But that is not consistent
with the Example#1 i.e.
print f(1)
print f(2)
print f(3)
prints
[1]
[1, 2]
[1, 2, 3]
The unnamed object that I imagined should have the value [], and L
should get set to [] every time that f() is called without a value
specified for L.
The alternative explanation that I could think of is that L is bound
to the unnamed object [], and the object itself changes values to
reflect changes to L i.e. L is now a persistent variable, retaining
its value between function calls unless a value is provided for L in
the function call's argument list. In the latter case, one can
imagine L simply being overwritten with the value provided.
The problem with this picture is that Example#2 should fail for the
same reasons as Example#1. That is, L will not get the value of None
on the 2nd call to f() without a value specified for L. Hence, L will
not be reset to [].
I searched through the tutorials for programmers. The same idiom is
presented, but I can't seem to find a more detailed explanation. Some
threads here presented None as something that gets treated differently
from a value, so I confirmed from the language reference that None is
not just a value, but its own type. The thread "Default Parameters to
function!" quotes the language reference in saying that the object
that L is bound to actually gets changed, when the function body makes
changes to the variable L. Again, if this was the case, it seems like
that should cause Example#2 to fail as well (obviously something I'm
missing here).
I'd appreciate it if someone could provide an explanation that's
suitable for my background (some C++ experience, but not a
practitioner of the more advanced concepts). Thanks.
Fred
I'm looking at Python for the 1st time today, motivated by its clarity
of syntax. I've looked at the tutoarial at
http://www.python.org/doc/current/tut/tut.html, particularly at the
section about default arguments. I've got some C++/STL under my belt,
so I'm familiar with passing/returning by reference, by value, and by
pointers. I've also used containers of pointers, as well as c++
default parameter values. I am aware of the general idea of reference
counting, but have never used it.
From the python tutorial, it's clear that to avoid sharing default
values between function calls, one has to avoid:
Example#1
---------
def f(a, L=[]):
L.append(a)
return L
Instead, one should use:
Example#2
---------
def f(a, L=None):
if L is None:
L = []
L.append(a)
return L
None has been described a analogous to the NULL value in c++. I'm
been looking and googling this newsgroup to get a clearer explanation
of why this works. The tutorial says that the default value is only
evaluated once. By that, I assume that there is some unnamed object
that is given the value of the 1st and only evaluation of the default
expression. Every time the function is called without an L parameter,
L gets the value of this unnamed object. But that is not consistent
with the Example#1 i.e.
print f(1)
print f(2)
print f(3)
prints
[1]
[1, 2]
[1, 2, 3]
The unnamed object that I imagined should have the value [], and L
should get set to [] every time that f() is called without a value
specified for L.
The alternative explanation that I could think of is that L is bound
to the unnamed object [], and the object itself changes values to
reflect changes to L i.e. L is now a persistent variable, retaining
its value between function calls unless a value is provided for L in
the function call's argument list. In the latter case, one can
imagine L simply being overwritten with the value provided.
The problem with this picture is that Example#2 should fail for the
same reasons as Example#1. That is, L will not get the value of None
on the 2nd call to f() without a value specified for L. Hence, L will
not be reset to [].
I searched through the tutorials for programmers. The same idiom is
presented, but I can't seem to find a more detailed explanation. Some
threads here presented None as something that gets treated differently
from a value, so I confirmed from the language reference that None is
not just a value, but its own type. The thread "Default Parameters to
function!" quotes the language reference in saying that the object
that L is bound to actually gets changed, when the function body makes
changes to the variable L. Again, if this was the case, it seems like
that should cause Example#2 to fail as well (obviously something I'm
missing here).
I'd appreciate it if someone could provide an explanation that's
suitable for my background (some C++ experience, but not a
practitioner of the more advanced concepts). Thanks.
Fred