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

Stef Mientki stef.mientki at gmail.com
Sun Oct 11 05:45:00 EDT 2009


thanks very much Stephen,

This is the first time I become aware of the difference between script 
and module !!
Starting with the wrong book "Learning Python" second edition, from Lutz 
and Ascher, based on Python 2.3"
in combination with using Python only from a high level IDE 
(PyScripter), (never seeing the m-switch),
I never was aware of this important difference.
A quick Googling on "python module vs script" doesn't reveal many (good) 
links,
the best one I found is
  http://effbot.org/zone/import-confusion.htm

thanks again,
Stef Mientki

Stephen Hansen wrote:
> On Sat, Oct 10, 2009 at 4:36 PM, Stef Mientki <stef.mientki at gmail.com 
> <mailto: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
>




More information about the Python-list mailing list