Why import only at module level?

John Roth newsgroups at jhrothjr.com
Thu Feb 19 22:39:23 CET 2004


"Paul Rubin" <http://phr.cx@NOSPAM.invalid> wrote in message
news:7xoervxwxt.fsf at ruckus.brouhaha.com...
> That's what the Python style guides advise.  They don't seem to like
>
>    def frob(x):
>       import re
>       if re.search('sdf[234]xyz', x): ...
>
> instead preferring that you pollute your module's global namespace
> with the names of all your imports.  What's the point of that?  It
> gets worse when you want to do something like
>
>    def dispatch(obj):
>       from types import *
>       if type(obj) == ListType: obj_list(obj)
>       elif type(obj) == FunctionType: obj_fcn(obj)
>       ...
>
> here you actually get a syntax warning that "from ... import *" is not
> ALLOWED except at the module level.  So the pollution is really
> serious in that case, you're spewing all the names from the imported
> module into your own module.  And I know that "import *" is considered
> uncool these days, but sometimes you really do want to just grab all
> those symbols, and the whole point of wanting the import inside the
> function is to contain the big import to a limited scope where they
> won't conflict with your own symbols.
>
> So what's the reason for the syntax warning, and for the convention of
> putting the imports at the top of the module?

The reason to put imports at the top of the module
is that, in general, imported modules are global resources. That's
also why it's not an issue to insert them in the module level
namespace.

Also, there are certain very common program tasks, such
as creating a subclass, where the superclass has to be
available at module load time. If it's in another module, that
module has to be imported before defining the class.

That said, if a module isn't a global resource then there's
no particular reason to put the symbol in the module
symbol table. I use __import__ in my version of FIT
to import fixtures into a dictionary, for example. I prefer
that technique to attempting to exec a constructed
import statement precisely because I don't have any
control over the names of the imported modules.

>From foobar import * is a specialized case that
should be used only when you know what the module
is going to import. If you don't want the scatter shot
loading, then just import foobar, and reference foobar.whatever
whenever you need a symbol. No one is holding an
assault weapon to your head to make you use import *
after all.

If you're a control freak (or your program analysis tools
barf on import *), you can always put assignments
for the symbols you're going to use after the imports.
That makes it explicit.

John Roth






More information about the Python-list mailing list