[Tutor] using a function as a dictionary value?

Kent Johnson kent37 at tds.net
Mon Dec 13 13:57:45 CET 2004


Liam Clarke wrote:
> Hey Justin,
> 
> Tricky one this..
> 
> as far as I know, and I'm a beginner myself, a dictionary stores a
> reference to the function, not the actual function.

Yes. In fact this is a good way to think about all variables in Python. A variable stores a 
reference to a value, not the value itself. I think of variables as somehow pointing at the value. 
Some people like to think of the variable as a sticky note stuck on the value with its name. 
Pythonistas say that the name is 'bound' to the value; the assignment 'x = 2' binds the name 'x' to 
the value '2'.

The *wrong* way to think about variables in Python is to think of them as containers that hold a 
value. This is appropriate for some languages but it is not a helpful model for Python.

> So - 
> 
> 
>>command = {'1': spam(),
>>            '2': breakfast(),
>>            '3': bridgekeeper()
>>            }
> 
> 
> Try this instead - 
> 
> command = {'1': spam, '2':breakfast, '3': bridgekeeper}

Yes. The difference is, you are storing a reference to the actual function object, rather than the 
result of calling the function.

 >>> def foo():
...   return 3
...

The function name is actually a variable which is bound to a function object. When you use the bare 
variable name, you are referring to this object:
 >>> foo
<function foo at 0x008D6670>

On the other hand when you use the function name with parentheses, you call the function. The value 
of this expression is the return value of the function.

 >>> foo()
3

Here is a dictionary with both usages:
 >>> d = { 'foo':foo, 'value':foo() }
 >>> d
{'foo': <function foo at 0x008D6670>, 'value': 3}

If you put foo in the dict, you have access to the function. If you put foo() in the dict, you have 
access to the result of calling the function. If I store a reference to the function, I can retrieve 
it and call it like this:
 >>> d['foo']()
3

Kent

>>if select in options:
>>    command[select]
> 
> 
> change this to - 
> 
> select = raw_input('Chose an option [1|2|3]: ')
> 
> if select in command.keys():
>      command[select]()
> 
> 
> 
> That one had me going round in circles when I first met it.
> AFAIK, everything is stored in dictionaries apparently. If you have a
> function called 'dude()' you could probably call it as a dictionary of
> 'dude' from the namespace...

Yes, under the hood, binding a name to a value turns into adding a mapping to a special dictionary. 
For variables with global scope, you can access this dictionary with the globals function. Both the 
dict d and the function foo are in my globals:

 >>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'foo': <function foo at 
0x008D6670>, '__doc__': None, 'd': {'foo': <functi
on foo at 0x008D6670>, 'value': 3}}
 >>> globals()['d']
{'foo': <function foo at 0x008D6670>, 'value': 3}

> 
> Standard disclaimer - 
> 
> Someone more knowledgable would probably be along shortly to point out
> a simpler, elegant way to do it, but my way works. Mostly.

Actually you got the code right :-) I just thought the explanation needed a little fleshing out.

Kent


More information about the Tutor mailing list