code in a module is executed twice (cyclic import problems) ?

Stephen Hansen apt.shansen at gmail.com
Sat Oct 10 20:24:34 EDT 2009


On Sat, Oct 10, 2009 at 4:36 PM, Stef Mientki <stef.mientki at gmail.com>wrote:

> hello,
>
> I always thought code in a module was only executed once,
> but doesn't seem to be true.
>

This is one of the reasons why that whole big mess of a ton separate scripts
that all call each-other and are sometimes imported and sometimes executed
is just a bad way to achieve code re-use and organization... :) IMHO :)


> I'm using Python 2.5.
>
> And this is the example:
>
> == A.py ==
> My_List = []
>
> == B.py ==
> from A import *
> My_List.append ( 3 )
> print 'B', My_List
> import C
>
> == C.py ==
> from A import *
> from B import *
> print 'C', My_List
>
> Now when you start with B.py as the main program,
> this is the resulting output:
>
> B [3]
> B [3, 3]
> C [3, 3]
>
> Why is the B.py executed twice ?
>

Because when you start B, it's not the module "B". Its a script that is
being run. Python doesn't byte-compile such scripts, nor do those scripts
count really as the modules you're expecting them to be.

When you "import B" after executing B as a main module, it won't find that
module "B" has already been loaded. When you execute B directly, its
actually the module "__main__". When you "import B", it's the module "B".

It's really better all around for "modules" to be considered like libraries,
that live over There, and aren't normally executed. Then you have scripts
over Here which may just be tiny and import a module and call that module's
"main" method. Okay, I'm not arguing you should never execute a module,
sometimes its useful and needful-- especially for testing or more complex
project organization. But in general... this is just gonna cause no end of
suffering if you don't at least try to maintain the "script" vs "module"
mental separation. Modules are the principle focus of code-reuse and where
most things happen, scripts are what kickstart and get things going and
drive things. IMHO.

If not that, then at least make sure that nothing is ever /executed/ at the
top-level of your files automatically; when imported call 'module.meth()' to
initialize and/or get My_List or whatever, and when executed use the
__name__ == "__main__" block to do whatever you want to do when the file is
started as a main script.

Otherwise, things'll get weird.

... gah snip huge write-up I threw in about how we organize our code around
the office. Not important! Your use-case is probably different enough that
you'd surely organize differently. But still, I really recommend treating
"modules" like static repositories of code that "scripts" call into / invoke
/ execute. Even if sometimes you execute the modules directly (and thus use
a main() function to run in whatever default way you choose).

HTH,

--S
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20091010/d729b92b/attachment-0001.html>


More information about the Python-list mailing list