Bizarre behavior with mutable default arguments
gagsl-py2 at yahoo.com.ar
Tue Jan 1 19:48:33 CET 2008
En Tue, 01 Jan 2008 15:45:00 -0200, bukzor <workitharder at gmail.com>
> On Jan 1, 9:00 am, bukzor <workithar... at gmail.com> wrote:
>> On Dec 31 2007, 1:30 pm, "Chris Mellon" <arka... at gmail.com> wrote:
>> > And also removing the only way you can currently do early binding in
>> > Python. I agree that it's a gotcha, but unless someone comes up with
>> > an answer to the following questions, I'll stick with the status quo
>> > (Note that this is not blind Python group-think as a previous poster
>> > implied, but a pragmatic decision that this is the most practical
>> > solution):
>> > a) If we don't evaluate default arguments at function compilation,
>> > when do we do it?
>> > b) If you do it at call time, how do you implement early binding?
>> I'm confused by what you mean by 'early binding'. Can you give a quick-
>> n-dirty example?
> Is an 'early bound' variable synonymous with a 'static' variable (in
No. It means, in which moment the name gets its value assigned. Usually
Python does "late binding", that is, names are resolved at the time the
code is executed, not when it's compiled or defined.
Consider this example:
z = 1
foo(3) # prints 4
z = 20
foo(3) # prints 23
The second time it prints 23, not 4, because the value for z is searched
when the code is executed, so the relevant value for z is 20.
Note that if you later assign a non-numeric value to z, foo(3) will fail.
If you want to achieve the effect of "early binding", that is, you want to
"freeze" z to be always what it was at the time the function was defined,
you can do that using a default argument:
z = 1
def foo(a, z=z)
z = None
foo(3) # prints 4
This way, foo(3) will always print 4, independently of the current value
of z. Moreover, you can `del z` and foo will continue to work.
This is what I think Chris Mellon was refering to. This specific default
argument semantics allows one to achieve the effect of "early binding" in
a language which is mostly "late binding". If someone changes this, he has
to come with another way of faking early binding semantics at least as
simple as this, else we're solving an [inexistant for me] problem but
creating another one.
More information about the Python-list