when to use import statements in the header, when to use import statements in the blocks where they are used?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Feb 9 04:32:02 CET 2012


On Tue, 07 Feb 2012 21:41:49 -0500, Dave Angel wrote:

> On 02/07/2012 09:32 PM, Patto wrote:

>> However I find in the file path/to/djcelery/loaders.py from
>> django-celery source, there are so many import/from statements used
>> inside functions, I do not know why the author coded like this. Are
>> there any special facts?
>>
>>
> I can't speak for django or django-celery.  There are people that
> disagree on this, and there are some reasons to override the ones I
> mentioned.  One would be large modules that are not used in most
> circumstances, or not used till the program has run for a while.
> 
> If you put the import inside a function, you can save on startup time by
> deferring some of the logic till later.  And if there's a module that
> probably won't be used at all (eg. an error handler), perhaps you can
> avoid loading it at all.

Yes, the idea is "lazy importing" -- add the module name to the namespace, 
but don't actually load it until necessary. Apparently it is used heavily 
in Django and by PyPy.

Interestingly, the CPython developers are currently migrating the low-
level import machinery from C to pure Python (or at least mostly pure 
Python), because

(1) the C code is a mess and practically nobody understands it; 
(2) the exact import behaviour is very hard to explain; 
(3) consequently Jython, IronPython etc. may behave slightly differently;
(4) and they'd like to share the same code base as CPython; and
(5) it's really hard to write custom importers.

Moving to a pure Python implementation should fix these problems, 
provided that the speed hit isn't too big.

http://sayspy.blogspot.com.au/2012/02/how-i-bootstrapped-importlib.html


One suggestion made is that Python should support lazy imports out of the 
box.

Another reason for putting imports inside a function is that global 
imports are, well, global. If you only need access to a module from one 
function, why pollute the global namespace?

A reason for *not* importing inside a function is that there can 
sometimes be strange effects with threads, or so I've been told, but I 
couldn't begin to explain exactly what (allegedly) can go wrong.


> I still think readability trumps all the other reasons, for nearly all 
> programs.

Which is a good reason for importing inside a function: why confuse the 
reader with a global import if it isn't needed globally?



-- 
Steven



More information about the Python-list mailing list