[Tutor] How the shell relates to programs in idle

Alan Gauld alan.gauld at yahoo.co.uk
Tue Feb 25 18:04:20 EST 2020


On 25/02/2020 14:48, daniel rieder wrote:

> when a program is run, the variables ... created in a program that is run from idle are retained

We need to be careful about the terminology here.

When you run a program in IDLE it is executed in the IDLE shell.
When the program stops the shell still runs so any data objects created
by the program will still exist and you can inspect them. But only the
objects that still live at the end of the program, not all the objects
that the program created.

> Here is the program:
> 
> 
> def createDictionary():
> 
>     '''Returns a tiny Spanish dictionary'''
> 
>     spanish = dict()
>     spanish['hello'] = 'hola'
>     spanish['yes'] = 'si'
>     spanish['one'] = 'uno'
...
>     spanish['blue'] = 'azul'
> 
>     return spanish

An easier way to do this is to create the dictionary in place:

spanish = {
'hello' : 'hola',
'yes'   : 'si',
'one'   : 'uno',
...
'blue'  : 'azul'
}
return spanish

Saves typing and is marginally faster to execute.
But thats a side issue...

Here is the key point.

> def main():
> 
>     dictionary = createDictionary()
>     print(dictionary['two'])
>     print(dictionary['red'])

When you create an object inside a function the object
only exists within that function, unless you return it
to the caller of the function.

So when you call createDictionary() you create spanish
inside the function. But because you return spanish,
the object is passed out to the caller(main) when
the function terminates. So  the dictionary is now referenced
by the variable name 'dictionary' which exists inside main.

But because you don't return dictionary to a variable
outside main, it dies when main ends.

So when the program finishes and you try to access the
data it is no longer there. The only objects left are
the two functions createDictionary() and main().


> When I ran the program, it displayed ‘dos’ and ‘rojo’ as intended.  

Good. The program works.

> Then immediately afterward, using the shell, I typed in: 
> print (dictionary[‘two’]) hoping it would access the dictionary 
> and print “dos,” but it returned an error message:
> 
> Traceback (most recent call last):
>   File "<pyshell#10>", line 1, in <module>
>     print (spanish['two'])
> NameError: name 'dictionary' is not defined

That's because the dictionary variable only exists inside main().
You cannot see it outside of main.

> Did I make a mistake in how I referenced the dictionary?  

No, you did everything correctly. Its just how Python
(and most other programming languages) work.

>...after the program is run like it seems to store variables…like it did  x

I suspect the x was not inside a main() function, but just typed at
the top level. If you had run the same program as above but left out
the def main() you would have seen the dictionary at the end. It
was just because you put it inside main that you lost it.

But I need to stress that you should not build programs where you
expect to access data after the program is finished. Think of
that purely as a debugging aid in IDLE. If you rely on it you
will only ever be able to run your programs inside IDLE and
that is not a good thing.

Instead you will learn to build programs that run continuously
until you tell them to exit. Then inside the program you will
create facilities for accessing the data as needed. That is a
much more user friendly way to write code and also more efficient.

If you want to read more about this topic (which is technically
called "scope" or "namespaces") and how to  deal with it check
out the "What's in a name?" advanced topic in my tutorial
(see .sig below)

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list