Py4Science

Newbie Nuggets

Oct 2, 2013

Each week we start the p4science meeting with a quick ipython notebook providing newer users with python examples that they can add to their collection of tools, and possibly show them existing functionality in libraries that they may not have been exposed to in their work.

These are meant to be quick stand-alone examples, hopefully with a meaningful application.

if __name__ == '__main__'

From the Python Docs:

__main__ top level script environment

This module represents the (otherwise anonymous) scope in which the interpreter’s main program executes — commands read either from standard input, from a script file, or from an interactive prompt. It is this environment in which the idiomatic “conditional script” stanza causes a script to run:

hmmmm....

Decoded

Given a python file <filename>.py. Code contained under if __name__ == '__main__':

Lets look at a simple example:

tempfile

We need to generate a few temporary files for this example. So lets look at an efficient method for handling tempfiles.

tempfile module ref.

tempfile is a wonderful library to create a temporary file or directory. On all supported platforms it will securely create a temporary directory (eg in /var/tmp or in /tmp on unix-like systems)

The creator is responsible for cleaning up the directory.

We need this below, as we will be generating two .py files. It doesnt matter where they are located, as long as we know where they are and can read and write them.

First I just want to generate a temporary directory to hold our files.

In [1]:
import os
import tempfile

tmpdir = tempfile.mkdtemp()
print tmpdir
/var/folders/0b/vldk0yzn4w9cswl86tr0xyhc0000gp/T/tmpU8B6Uv

First I want to make a script that just imports another module. It does nothing itself, just runs the applicable code when it loads the module.

the file module_one.py should contain only one line

import module_two
In [2]:
# Lets make a module that just imports another module 
file_one = os.path.join(tmpdir, 'module_one.py')


with open(file_one, 'w+') as fid:
    fid.write("""import module_two""")

Ipython magic (a small aside)

If we just wanted to create the file locally (in the same directory as this notebook), we could use the %%file magic. So in one cell you could put

%%file module_one.py

import module_two

And it would write to a file named module_one.py. This may be easier than using a tempfile interface, use whichever you prefer.

In [2]:
%%file module_one.py

import module_two
Writing file_one

module_two.py

This module has code

In [3]:
# now lets make the other module in our temp directory
file_two = os.path.join(tmpdir, 'module_two.py')
with open(file_two, 'w+') as fid:
    fid.write("""
print 'I am outside __main__ , my name is: %s'%__name__

if __name__ == '__main__':
    print 'Inside if __name__ == __main__ , my name is: %s'%__name__

""")
    
In [4]:
## Lets make sure the files exist
os.listdir(tmpdir)
Out[4]:
['module_one.py', 'module_two.py']

Order of operation, limit of scope

Now lets run the files and see what they return.

In [5]:
%run $file_one  #basically just imports module_two
I am outside __main__ , my name is: module_two

In [6]:
%run $file_two #runs its own code in order
I am outside __main__ , my name is: __main__
Inside if __name__ == __main__ , my name is: __main__

Discussion

Running module_one.py

When module_one.py is run, it just imports module_two.py:

python module_one.py

printing this:

I am outside __main__ , my name is: module_two

We can now see the order in which the script is run.

Only items outside of the if __name__ == "__main__": block get executed (though in this case there is no if __name__ == '__main__': block), and __name__ points to the module imported, namely module_two

Running module_two.py

When module_two.py is run, it

Then

so the output is:

I am outside __main__ , my name is: __main__
Inside if __name__ == __main__ , my name is: __main__

python flags

A kind suggestion during our meeting was to use the -m flag when calling python to run a library module as a script.

-m mod : run library module as a script (terminates option list)

for example

 python -m IPython
 python -m <pkg>.tests

Important NOTE in Python 2.6 (and only 2.6) you cannot run package as a script

Emacs Note

integrated with emacs, did not work link emacs to ipython

One of the users has a emacs/ipython setup that allows her to run scripts from her editor. This had an odd peculiarity. It would not run the if __name__ == '__main__': block.

print "hi"
print __name__

if __name__ == '__main__':
    print 'there'

print "hello"

and thus resulted in this output

hi
__main__
hello

it is a peculiarity to this setup.

Why oh why would I do this??

Adding a if __name__ == '__main__': to your script can have a few useful behaviors.