Enums are Singletons - but not always?
On 5/23/2020 2:21 PM, Ralf M. wrote:
> ##### Code of mod1.py #####
> import enum, mod2
> class En(enum.Enum):
> ??? A = 1
> ??? B = 2
> def main():
> ??? a = mod2.getA()
> ??? print("a is En.A:", a is En.A)
> ??? print("a:", repr(a), "??? En.A:", repr(En.A))
> ??? print("id(a), id(a.__class__)", id(a), id(a.__class__))
> ??? print("id(En.A), id(En)????? ", id(En.A), id(En))
> if __name__ == "__main__":
> ??? main()
> ##### Code of mod2.py #####
> import mod1
> def getA():
> return mod1.En.A
As a couple of people mentioned, the issue is the circular import. When
you run mod1 from a command line, its name is __main__. Its execution
of mod1 code stops to execute enum code and then mod2 code.
Execution of mod2 stops to execute mod1 code in a new module named
'mod1'. When the second execution of mod1 code does the import of enum
and mod2, sys.modules['enum'] and sys.modules['mod2'] exist, are found,
and used to satify the import. So enum and mod2 code are not executed
again. In the 'mod1' module, 'mod2' is linked to the *incomplete* mod2.
This 'works' in your code because the reference to mod2 within def
main is not used because the name is 'mod1', not '__main__'. But if in
mod1, you had written
from mod2 import getA
the second execution of mod1 would fail because mod2.getA does not exist
because execution of mod2 is paused to import mod1
When the mod1 import in mod2 finishes, the execution of mod2 code for
'mod2' finishes without issue. Then the execution of 'mod1' code in
'__main__' finishes with the call to main.
When you instead interactively import mod1, it is executed just once and
you have to explicitly call main.
In idlelib, pyshell currently has the IDLE Shell code, the main()
function, and a couple of classes used elsewhere. (An atrocious design
that I inherited and have only partly fixed.) As a *temporary* fix to
an issue due to there being duplicate '__main__' and 'pyshell' modules,
I added the following to the top of pyshell.
if __name__ == "__main__":
But doing what others suggested, limiting the main or start module to
one-time code, is better.
Terry Jan Reedy