PEP 8 exegetics: conditional imports?

Dave Angel davea at ieee.org
Fri Aug 7 16:16:01 EDT 2009


Albert Hopkins wrote:
> On Fri, 2009-08-07 at 16:50 +0000, kj wrote:
>   
>> Conditional imports make sense to me, as in the following example:
>>
>> def foobar(filename):
>>     if os.path.splitext(filename)[1] == '.gz':
>>         import gzip
>>         f = gzip.open(filename)
>>     else:
>>         f = file(filename)
>>     # etc.
>>
>> And yet, quoth PEP 8:
>>
>>     - Imports are always put at the top of the file, just after any module
>>       comments and docstrings, and before module globals and constants.
>>
>> ...which seems to condemn conditional imports unequivocally. 
>>
>> Then again, the PEP 8 scriptures do not explicitly mention conditional
>> imports at all, as far as I can tell, which leaves open the
>> possibility that they are still righteous. 
>>
>> In fact, venerable passages in the Python standard library source
>> code, if properly interpreted, can be seen to carry out conditional
>> imports, such as this fragment recovered from random.py:
>>
>>         if a is None:
>>             try:
>>                 a = long(_hexlify(_urandom(16)), 16)
>>             except NotImplementedError:
>>                 import time
>>                 a = long(time.time() * 256) # use fractional seconds
>>
>> Or even more clearly, this one from test/pystone.py:
>>
>> if __name__ == '__main__':
>>     import sys
>>
>>
>>     
>
> I can't speak for others... but generally you can "tell" when an import
> belongs at the top of a module and when you need to make exceptions.  I
> would say that, as a general rule, they go up top (easier to identify
> what external dependencies a module have).  There are, of course,
> exceptions:
>
>       * Exceptions and other not-often-executed blocks
>       * Inside test functions (where the imported modules are only used
>         by tests
>       * Inside main() functions where the imported modules are only used
>         if the module is run as a script
>       * When startup-time is important. Often it's necessary to have you
>         module up and running in an instant and import "expensive"
>         modules as-needed.
>       * "Dynamic" import such as plugins, etc.
>
> Of course, like everything else in PEP 8, it's meant as a "guide" and
> not as an "order".  YMMV.
>
> -a
>
>
>   
Excellent points.  I'd add a couple more, one pro, and two con:

You need conditionals when you're doing things that are 
environment-specific.  For example, you might use Win32 stuff when on 
Windows, and something else when on Linux.  So you might have a pair of 
modules which encapsulate the non-portable aspects, and conditionally 
import one of those.

You usually want any imports to be complete before starting 
multithreading.  As somebody else has recently pointed out, there's an 
import-lock that's active during imports,

If two modules do mutual imports (not a good idea, but it is sometimes 
practically unavoidable), the earlier in the file that the import 
happens, the less likely for a problem to crop up.  So try to put them 
at the top.





More information about the Python-list mailing list