15.04.2013 Views

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

Core Python Programming (2nd Edition)

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Most projects tend to consist of a single application and import any required modules. Thus it is<br />

important to bear in mind that most modules are created solely to be imported rather than to execute as<br />

scripts. We are more likely to create a <strong>Python</strong> library-style module whose sole purpose is to be imported<br />

by another module. After all, only one of the modulesthe one that houses the main applicationwill be<br />

executed, either by a user from the command line, by a batch or timed mechanism such as a Unix cron<br />

job, via a Web server call, or through a GUI callback.<br />

With that fact in hand, we should also remember that all modules have the ability to execute code. All<br />

<strong>Python</strong> statements in the highest level of codethat is, the lines that are not indentedwill be executed on<br />

import, whether desired or not. Because of this "feature," safer code is written such that everything is in<br />

a function except for the code that should be executed on an import of a module. Again, usually only the<br />

main application module has the bulk of the executable code at its highest level. All other imported<br />

modules will have very little on the outside, and everything in functions or classes. (See <strong>Core</strong> Note that<br />

follows for more information.)<br />

<strong>Core</strong> Note: __name__ indicates how module was loaded<br />

Because the "main" code is executed whether a module is imported or<br />

executed directly, we often need to know how this module was loaded<br />

to guide the execution path. An application may wish to import the<br />

module of another application, perhaps to access useful code which<br />

will otherwise have to be duplicated (not the OO thing to do).<br />

However, in this case, you only want access to this other application's<br />

code, not necessarily to run it. So the big question is, "Is there a way<br />

for <strong>Python</strong> to detect at runtime whether this module was imported or<br />

executed directly?" The answer is ... (drum roll ... ) yes! The __name__<br />

system variable is the ticket.<br />

3.4.2. Create Tests in the Main Body<br />

● __name__ contains module name if imported<br />

● __name__ contains '__main__' if executed directly<br />

For good programmers and engineers, providing a test suite or harness for our entire application is the<br />

goal. <strong>Python</strong> simplifies this task particularly well for modules created solely for import. For these<br />

modules, you know that they would never be executed directly. Wouldn't it be nice if they were invoked<br />

to run code that puts that module through the test grinder? Would this be difficult to set up? Not really.<br />

The test software should run only when this file is executed directly, i.e., not when it is imported from<br />

another module, which is the usual case. Above and in the <strong>Core</strong> Note, we described how we can<br />

determine whether a module was imported or executed directly. We can take advantage of this<br />

mechanism by using the __name__ variable. If this module was called as a script, plug the test code right<br />

in there, perhaps as part of main() or test() (or whatever you decide to call your "second-level" piece of<br />

code) function, which is called only if this module is executed directly.<br />

The "tester" application for our code should be kept current along with any new test criteria and results,<br />

and it should run as often as the code is updated. These steps will help improve the robustness of our<br />

code, not to mention validating and verifying any new features or updates.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!