accessing variable of the __main__ module
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Sat Mar 20 09:05:41 EDT 2010
On Sat, 20 Mar 2010 13:16:08 +0100, News123 wrote:
> Hi,
>
>
> I wondered about the best way, that a module's function could determine
> the existance and value of variables in the __main__ module.
>
>
> What I came up with is:
> ########### main.py ##########
> import mod
> A = 4
> if __name__ == "__main__": mod.f()
> ########### mod.py ##########
> def f():
> try:
> from __main__ import A
> except ImportError as e:
> A = "does not exist"
> print "__main__.A" ,A
>
> Is there anything better / more pythonic?
First problem:
You try to import from "__main__", but the other module is called "main".
__main__ is a special name, which Python understands as meaning "this
module that you are in now". For example:
$ cat test_main.py
x = "something special"
import __main__ # magic alias for this module
print __main__.x
$ python test_main.py
something special
So inside "mod.py", the line "from __main__ import A" tries to import A
from mod.py, not from main.py. You need to say "from main import A"
instead.
But if you do this, it creates a second problem: you have a circular
import, which is generally considered a Bad Thing. The problem is that:
(1) module main tries to import module mod
(2) module mod tries to import module main
(3) but main is still waiting for mod to be imported
Now, in your case you escape that trap, because the import is inside a
function, so it doesn't occur until you call the function. But it is
still considered poor practice: it is best to avoid circular imports
unless you really, really need them.
The question is, why does module mod.py care what is happening in
main.py? It is better for mod.py to be self-contained, and not care about
main.py at all. If it needs A, let the caller pass A to it:
########### main.py ##########
import mod
A = 4
if __name__ == "__main__":
mod.f(__name__, A)
########### mod.py ##########
def f(caller, A):
print "%s.A: %s" % (caller, A)
--
Steven
More information about the Python-list
mailing list