Placement of Python Import Statements

Pep 8 specifies that all import statements should be "put at the top of the file, just after any module comments and docstrings, and before module globals and constants." However, it does not really specify the logic behind this. I'm going to try to articulate some reasons to have import statements somewhere other than directly at the top of the file. I'll also state some arguments for having such import statements at the top.

Note, that Pep 8 also specifies that it is important to "know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment". So the purpose of this post is to suggest some reasons why you might deviate from the style guide with respect to import statements at the top.

Conditional Import

There are some obvious reasons not to have a particular import statement directly at the start of the file. The most obvious is if you have an optional path in your application such that you have an optional dependency. So you may have something like:

if '--mail' in sys.args:
    import fancy.mail.library.module

Knowing that if the --mail option is not supplied then the module fancy.mail.library.module is never referenced, hence you can avoid importing it and avoid failing if the dependency is missing. You may also do this if the module in question has a long import time, since you want to avoid the penalty for importing it if it is not going to be used.

Neither of these obvious reasons really breaks the spirit of the PEP. If you do this at the head of the importing module then although you are technically importing within a conditional statement, you're still doing so at the head of the module. However, there may be a good reason to perform this test only once. For example you may write at the bottom of your module:

if __name__ == '__main__':
    if '--mail' in sys.args:
        import fancy.mail.library.module as mail
        do_work_with_mailer(mail.mailer())
    else:
        do_normal_work()

This means that you only test for the --mail option once.

Bunching Imports With Relevant Code

I find I occasionally wish to bunch related definitions together. When I do so, they often collectively rely on some imports that are not relevant for the rest of the module I'm writing.

A good feature of this is that import statements can be kept a bit leaner. When the import statement is immediately above the code that uses it, you are more likely to delete it if you ever actually stop using the imported module. Some code analysis software will indeed help you to tidy up unused imports, which indeed weakens this point.

One argument against this, is that we have separate "bunches" of code then we should create a separate modules. I tend to be lean on creating new files. I do not like to create extra source modules without good reason. I find that doing so tends to solidify your structure. I have written about single-file programming at length elsewhere and may revisit the subject here again. But the whole topic is a bit out of scope here. If you believe in making lots of small modules, then yes keeping import statements near the related code is likely not a terribly convincing reason to break the PEP 8 guideline. Though note, doing so, might aid you in breaking out some code into a module of its own.

Reasons to Abide By Pep 8

One good reason to import modules only at the head of the importing module is that code within the module can be more easily moved around. If you scatter import statements around your module you have to be careful not to move any code that depends upon an imported module above that module's import statement.

If you're getting really fancy and placing import statements within non-trivial branching statements then you have to make sure that code which depends upon an import statement is never executed without the import statement.

A reasonable test suite will of course prevent you from making either mistake. But you simply do not open yourself up to this problem at all if you keep all of your import statements at the top of the module.

Conclusion

I find myself sticking most imports at the head of the module, mostly just to comply with pep8 because whilst I might not see the immediate benefit of this, any benefits of scattering the import statements throughout your module are minimal. So this means that it is generally, for me, worth it to keep the imports at the top. However, it can be well worth considering breaking such conventions/guidelines even it just forces you to consider the logic behind the conventions/guidelines in the first place. Blindly following a coding guideline often ends in using it where inappropriate.

Comments

Comments powered by Disqus