import in code

Cameron Simpson cs at cskk.id.au
Sun Jul 22 00:45:08 EDT 2018


On 22Jul2018 06:43, Abdur-Rahmaan Janhangeer <arj.python at gmail.com> wrote:
>i have found some reputable books that include import within code
>
>with ...
>    import x
>
>if ...
>    import y
>
>def ...
>     import z
>
>according to me they should be placed at the top. but an advantage of it is
>optimisation where you only load modules if necessary
>
>so, import within code can be called unpythonic?

It is discouraged, because when the imports are at the top they're really 
obvious. That is a huge gain for maintenance and readability.

Importing a module is _usually_ pretty cheap. There are some reasons to put off 
imports until the code which needs them runs, but they are all fairly rare:

Circular imports: 2 codependent modules. If you have:

  module A:
    import B

  module B:
    import B

That won't work: the second import (whichever it turns out to be) will fail.  
One workaround is to make one of the modules put off the import. A better 
approach is usually to redesign things so that they don't do a mutual import 
(move classses etc around, or merge them). This is always feasible, but often 
is.

External dependencies: if your module only sometimes needs a third party 
facility, you might put off importing that 3rd party module until it is 
actually needed.

As an example, I have a personal project, not yet released, which has a "mount" 
command, presenting stuff as a local filesystem using the "llfuse" Python 
module. Aside from that, everything else is self contained. By making the 
"mount" command do the "import llfuse", there isn't a general requirement for 
people to install llfuse unless the particularly want that facility.

Another example is probing the local environment for available facilities. You 
may have code that probes for various database backends, for example, and hooks 
up those found. This is a runtime thing which can happen in the main import 
block, but may well live better in some "probing" function lower in the module.

Antoher example is a variant on the above: modules like SQLAlchemy will accept 
"database connection URIs", like "mysql://hostname/...". The supporting module 
might only be loaded if such a URI is encountered.

Serverless or tiny workload situations: when a Python program is invoked very 
frequently, particularly to perform a tiny task, the fewer imports there are 
the (slightly) faster it will run. Also, sometimes a module might be expensive 
to import, itself pulling in a lot of other things. In a serverless 
architecture, Python gets invoked on every call, so making the setup (imports 
etc) as cheap as possible is suddenly much more important.

All of these situations may benefit from doing conditional or deferred imports.  
But try to avoid them until you have a specific need.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Python-list mailing list