I am dealing with some python code automatically generated for me. I want to avoid manually editing these python files & hence this question/issue:
foo.py:
def foo():
print "foo"
boo.py:
def boo():
foo.foo() # <-- global name 'foo' not defined
print "boo"
bar.py:
import foo
import boo
def bar():
boo.boo()
print "bar"
Execution of:
python.exe bar.py
gives an error that boo did not find foo. But bar is importing both foo & boo. Shouldn't foo be automatically available to boo?
Is there a way to do so? As said boo.py is automatically generated for me & I want to avoid adding import foo to boo.py
Thanks.
you have to import foo in boo
boo.py
bar.py
Each module has its own namespace. So for boo.py to see something from an external module, boo.py must import it itself.
It is possible to write a language where namespaces are stacked the way you expect them to: this is called dynamic scoping. Some languages like the original lisp, early versions of perl, postscript, etc. do use (or support) dynamic scoping.
Most languages use lexical scoping instead. It turns out this is a much nicer way for languages to work: this way a module can reason about how it will work based on its own code without having to worry about how it was called.
See this article for additional details: http://en.wikipedia.org/wiki/Scope_%28programming%29
No it shouldn't:
import
, like any other way to bind a name, binds that name in a single, specific scope, not "in all scopes you could ever possibly want it in".There's one very bad hack -- I wouldn't want to live with it (I'd much rather pour my energy into getting that totally broken code generator that makes
boo.py
fixed -- if it has such a huge bug as missing a crucial needed import, what other horrors can it have in store?!), but, hey, it ain't my funeral...;-)Have
bar.py
start...:This way you've made identifier
foo
a "fake, artificial built-in name" (the only kind of name that is available from every scope, unless shadowed by other intervening bindings of the name in closer scopes) referring to the modulefoo
.NOT recommended procedure, just a temporary workaround for the horrible, glaring bug in the code generator that builds
boo.py
. Get that bug fixed so you can retire this hack ASAP!No. If you want
foo
to be available inboo
, you need to import it inboo
. Theimport foo
that is inbar
only makesfoo
available in thebar
module.In general, an
import
statement in Python is kind of like a variable definition. You could actually think of it like that: mentally replacewith
(
__import__
is a builtin function of the Python interpreter that either imports a module, or looks up a reference to the existing module if it's already been imported, and returns that reference)Whatever is automatically generating
boo.py
is doing it wrong. It should be addingimport foo
somewhere within that file. You can get around it by doing this inbar.py
:but you really shouldn't have to be doing that. (I echo what Alex Martelli said about this kind of thing being a huge hack)