I thought I understood how import worked...

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Aug 7 09:52:59 EDT 2012


On Tue, 07 Aug 2012 09:18:26 -0400, Roy Smith wrote:

> I thought modules could not get imported twice.  The first time they get
> imported, they're cached, and the second import just gets you a
> reference to the original.  Playing around, however, I see that it's
> possible to import a module twice if you refer to it by different names.

Yes. You've found a Python gotcha.

The most common example of this is when a single file acts as both an 
importable module, and as a runnable script. When run as a script, it is 
known as "__main__". When imported, it is known by the file name. Unless 
you take care, it is easy to end up with the module imported twice.

The usual advice is "never have one module used as both script and 
importable module". I think *never* is a bit strong, but if you do so, 
you need to take extra care.

>  Here's a small-ish test case which demonstrates what I'm talking about
> (python 2.6.5):
> 
> In directory /home/roy/play/import/foo, I've got:
> 
> __init__.py  (empty file)
> try.py
> broken.py

Aside: calling a module "try.py" is asking for trouble, because you can't 
do this:

import try


> $ cat broken.py
> print __file__
> 
> 
> $ cat try.py
> import broken
> import foo.broken

Which are two names for the same module.


> So, it appears that you *can* import a module twice, if you refer to it
> by different names!  This is surprising.  It means that having
> non-idempotent code which is executed at import time is a Bad Thing.

Well yes. In general, you should avoid non-idempotent code. You should 
doubly avoid it during imports, and triply avoid it on days ending with Y.

The rest of the time, it is perfectly safe to have non-idempotent code.

:)

I kid, of course, but only half. Side-effects are bad, non-idempotent 
code is bad, and you should avoid them as much as possible, and unless 
you have no other reasonable choice.


> It also means that you could have multiple copies of a module's global
> namespace, depending on how your users imported the module.  Which is
> kind of mind-blowing.

Oh that part is trivial. Module namespaces are just dicts, there's 
nothing special about them.

py> import math  # for example
py> import copy
py> namespace = copy.deepcopy(math.__dict__)
py> math.__dict__ == namespace
True
py> math.__dict__ is namespace
False


It are modules which should be special, and Python tries really hard to 
ensure that they are singletons. (Multitons?) But not superhumanly hard.


-- 
Steven



More information about the Python-list mailing list