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:
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.
import os
import tempfile
tmpdir = tempfile.mkdtemp()
print tmpdir
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
# 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""")
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.
%%file module_one.py
import module_two
This module has code
if __name__ == '__main__':
block.if __name__ == '__main__':
block.# 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__
""")
## Lets make sure the files exist
os.listdir(tmpdir)
Now lets run the files and see what they return.
%run $file_one #basically just imports module_two
%run $file_two #runs its own code in order
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
When module_two.py
is run, it
if __name__ == '__main__':
Then
if __name__ == '__main__':
so the output is:
I am outside __main__ , my name is: __main__
Inside if __name__ == __main__ , my name is: __main__
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
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.
Adding a if __name__ == '__main__':
to your script can have a few useful behaviors.
allows you to import script items as a library
quick and dirty way to add tests to a script