change of random state when pyc created??

John Machin sjmachin at lexicon.net
Sat May 5 19:39:19 EDT 2007


On May 5, 1:48 pm, "Alan Isaac" <ais... at american.edu> wrote:
> This may seem very strange, but it is true.
> If I delete a .pyc file, my program executes with a different state!
>
> In a single directory I have
> module1 and module2.
>
> module1 imports random and MyClass from module2.

That's rather ambiguous. Do you mean
(a) module1 imports random and (MyClass from module2)
or
(b) module1 imports (random and MyClass) from module2

> module2 does not import random.

This statement would *appear* to rule out option (b) but appearances
can be deceptive :-)

It's a bit of a worry that you call the first file "module1" and not
"the_script". Does module2 import module1, directly or indirectly?

>
> module1 sets a seed like this::
>
> if __name__ == "__main__":
>     random.seed(314)
>     main()
>
> I execute module1.py from the (Windows) shell.
> I get a result, let's call it result1.
> I execute it again. I get another result, say result2.
> Running it again and again, I get result2.

Stop right there. Never mind what happens when you delete module2.pyc.
Should you not expect to get the same result each time? Is that not
the point of setting a constant seed each time you run the script?
====>>> Problem 1.

>
> Now I delete module2.pyc.
> I execute module1.py from the shell.
> I get result1.
> I execute it again; I get result2.
> From then on I get result2,
> unless I delete module.pyc again,
> in which case I once again get result1.
>
> Can someone explain this to me?
>
> Thank you,
> Alan Isaac

Compiling module2 is causing code to be executed that probably
shouldn't be executed. ===>>> Problem 2.

With all due respect to your powers of description :-) no, it can't be
explained properly, without seeing the contents of the source files. I
strongly suggest that if you continue to experience Problem1 and/or
Problem 2, you cut your two files down to the bare minima and post
them here.

Meanwhile,  my deja-vu detector is kicking in ...

uh-huh (1), from 25 April:
===
%%%%%  test2.py  %%%%%%%%%%%%%
from random import seed
seed(314)
class Trivial:
    pass
===
Is module2 (still) doing that?
Is module1 importing itself (directly or indirectly)?

uh-huh (2), the long thread about relative imports allegedly being
broken ...

It appears to me that you need to divorce the two concepts "module"
and "script" in your mind.

Modules when executed should produce only exportables: classes,
functions, NAMED_CONSTANTS, etc. It is OK to do things like process
the easier-to-create
_ds = """\
foo 1
bar 42
zot 666"""
into the easier-to-use
USEFUL_DICT = {'foo': 1, 'bar': 42, zot: 666}
but not to change global state.

Scripts which use functions etc from a module or package should be
independent of the module/package such that they don't need anything
more complicated than simple importing of the module/package. The
notion of inspecting the script's path to derive the module/package
path and then stuffing that into sys.paths is mind boggling. Are
module1/script1 and module2 parts of a package?

Here's a suggestion for how you should structure scripts:

def main():
    # All productive code is inside a function to take advantage
    # of access to locals being faster than access to globals
    import mymodule
    mymodule.do_something()
if __name__ == "__main__":
    main()
else:
    raise Exception("Attempt to import script containing nothing
importable")

and your modules should *start* with:
if __name__ == "__main__":
    raise Exception("Attempt to execute hopefully-pure module as a
script")

HTH,
John




More information about the Python-list mailing list