Python and the "extra stuff"

Wed 01 February 2012 by James Saryerwinnie

Learning a new programming language can be a daunting task. Even though you start with the basic things like syntax, in order to become productive in the language you must learn things like

  • Common coding idioms and patterns
  • The standard library
  • Best practices (including what frameworks to use, what development tools to use, etc)

But then there's also the, for lack of a better term, "extra stuff." The collection of miscellaneous tips and tricks you pick up while coding in the language on a day to day basis. These set of tips end up saving you a lot of time in the long run, but are hard to distinguish how useful a tip really is when you first hear about it.

Well, this is my list of tips. It's not 100% complete, and focuses mostly on various tidbits of information that, when I think about how I code on a day to day basis, I find myself repeatedly doing.

The _ variable

This tip is useful when you're in an interactive python shell. The _ variable stores the value of the most recently evaluated expression:

>>> 1 + 2 + 3
6
>>> _ * 24
144
>>> _ / 12.
12.0
>>> [i for i in range(100) if i < 10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> len(_)
10

Figuring Out Where to Look

Sometimes if you're trying to debug a problem you'll to need to figure out where a module is located. A really easy way to do this is to use the __file__ attribute of a module object:

>>> import httplib
>>> httplib.__file__
'/usr/local/lib/python2.7/httplib.pyc'

You can also use inspect.getfile(obj) to find where an object is located.

Running Your Module as a Script

Every module will have a __name__ attribute, but the value of that attribute will depend on how the module is executed. Consider a module:

python foo.py print __name__

When the module is imported the name will be "foo".

>>> import foo
foo
>>>

However, when the module is executed as a script, the name will be __name__:

$ python foo.py
__main__

It may not be obvious how this is useful. The way that this is typically used is to allow a module to be both imported and used as a script. Sometimes the script is a command line interface to the functionality available in the module. Sometimes the script provides a demo of the capabilities of the module. And sometimes the script runs any tests that live in the module (for example all of the doctests). To use this in your own library you can use something like this:

def do_something(args):
    # Do something with args.
    pass

def main(argv=None):
    if argv is None:
        argv = sys.argv
    args = parse_args(argv)
    do_something(args)


if __name__ == '__main__':
    sys.exit(main())

The main() function is only called when the module is run directly.

The -m option

Once your module has an if __name__ == '__main__' clause (I usually refer to this as just the ifmain clause), an easy way to invoke the module is to use the -m option of python. This allows you to refer to a module by its import name rather than its specific path. In the previous example the foo.py module could be run using:

$ python -m foo

One final thing worth pointing out is that many modules in python's stdlib have useful ifmain functionality. A few notable ones include:

python -m SimpleHTTPServer

This will serve the current working directory on port 8000. I use this command on almost a daily basis. From quickly downloading files to viewing html files on a remote server, this is one of the most useful ifmain clauses in the entire python standard library.

python -m pdb myfile.py

Run a python script via pdb (the python debugger).

python -m trace --trace myfile.py

Print each line to stdout before it's executed. Be sure to see the help of the trace module, there's a lot of useful options besides printing each line being executed.

python -m profile myfile.py

Profile myfile.py and print out a summary.

So there it is. My list of tips. In the future I plan on expanding on some of these tips in more depth (the profiling workflow for python code and how to debug python code stand out), but in the meantime, may these tips be as helpful to you as they are to me.


Comments