The os.startfile call
In fact, start is so useful that recent Python releases also include an os.startfile call,
which is essentially the same as spawning a DOS start command with os.system and
works as though the named file were double-clicked. The following calls, for instance,
have a similar effect:
>>> os.startfile('lp-code-readme.txt')
>>> os.system('start lp-code-readme.txt')
Both pop up the text file in Notepad on my Windows computer. Unlike the second of
these calls, though, os.startfile provides no option to wait for the application to close
(the DOS start command’s /WAIT option does) and no way to retrieve the application’s
exit status (returned from os.system).
On recent versions of Windows, the following has a similar effect, too, because the
registry is used at the command line (though this form pauses until the file’s viewer is
closed—like using start /WAIT):
>>> os.system('lp-code-readme.txt') # 'start' is optional today
This is a convenient way to open arbitrary document and media files, but keep in mind
that the os.startfile call works only on Windows, because it uses the Windows reg-
istry to know how to open a file. In fact, there are even more obscure and nonportable
ways to launch programs, including Windows-specific options in the PyWin32 pack-
age, which we’ll finesse here. If you want to be more platform neutral, consider using
one of the other many program launcher tools we’ve seen, such as os.popen or
os.spawnv. Or better yet, write a module to hide the details—as the next and final
section demonstrates.
A Portable Program-Launch Framework
With all of these different ways to start programs on different platforms, it can be
difficult to remember what tools to use in a given situation. Moreover, some of these
tools are called in ways that are complicated and thus easy to forget. Although modules
like subprocess and multiprocessing offer fully portable options today, other tools
sometimes provide more specific behavior that’s better on a given platform; shell win-
dow pop ups on Windows, for example, are often better suppressed.
I write scripts that need to launch Python programs often enough that I eventually wrote
a module to try to hide most of the underlying details. By encapsulating the details in
this module, I’m free to change them to use new tools in the future without breaking
code that relies on them. While I was at it, I made this module smart enough to auto-
matically pick a “best” launch scheme based on the underlying platform. Laziness is
the mother of many a useful module.
A Portable Program-Launch Framework | 263