[Tutor] Why is it invalid syntax to have a particular dictionary value as an argument?

Cameron Simpson cs at zip.com.au
Wed Apr 8 06:43:22 CEST 2015


On 07Apr2015 21:16, boB Stepp <robertvstepp at gmail.com> wrote:
>Despite Mark's warning, I feel I must see if I understand what is going on here.
>
>Switching to Py 3.4 since I am now at home:
>
>Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600
>64 bit (AMD64)] on win32
>Type "copyright", "credits" or "license()" for more information.
>>>> d = {'a': '123'}
>>>> def func(s=d['a']):
>              print(s)
>              print(d['a'])
>
>>>> func()
>123
>123
>>>> d['a'] = 'new value'
>>>> func()
>123
>new value
>
>I added an additional print to the function to show the dictionary
>entry's behavior.
>
>First, my current understanding is that this form of the function does
>not object to the presence of d['a'] in its parameter list because s
>is the real parameter, d['a'] is its default value, but s is not
>actually evaluated until run time.

Yes and no.

Yes to "s is the real parameter, d['a'] is its default value".

No to "s is not actually evaluated until run time".

When you _define_ the function, the _current_ value of d['a'] is stashed in the 
function definition as the default value.

When you _call_ the function, and omit the 's' parameter, the default value is 
used.

However, that value was _computed_ when the function was compiled: the function 
definition does not keep "d['a']" around for evaluation, instead that 
expression is evaluated when you define the function, and the reference to the 
resulting value kept around. That is thus '123'.

So when you go:

  d['a'] = 'new value'

the contents of the "d" dictionary have changed. But all that has happened is 
that the reference to '123' is no longer in the dictionary; instead a reference 
to 'new value' is in the dictionary.

When you call "func()" the name "s" is bound to the default value, which is the 
'123' as computed at function definition time. And it prints that. Of course, 
when you print "d['a']" it must evaluate that then, and finds 'new value'.

This is one reason why the common idion for default values looks like this:

  def func(s=None):
    if s is None:
      s = ... compute default here ...

Of course, the default is often a constant or some value computed earlier.

Cheers,
Cameron Simpson <cs at zip.com.au>

I think... Therefore I ride.  I ride... Therefore I am.
        - Mark Pope <erectus at yarrow.wt.uwa.edu.au>


More information about the Tutor mailing list