Python "import" scope
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
But bar is importing both foo & boo. Shouldn't foo be automatically available to boo?
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".
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
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...:
import foo
import boo
import __builtin__
__builtin__.foo = foo
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 module foo
.
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!
you have to import foo in boo
boo.py
import foo
def boo():
foo.foo() # <-- global name 'foo' not defined
print "boo"
bar.py
import boo
def bar():
boo.boo()
print "bar"
No. If you want foo
to be available in boo
, you need to import it in boo
. The import foo
that is in bar
only makes foo
available in the bar
module.
In general, an import
statement in Python is kind of like a variable definition. You could actually think of it like that: mentally replace
import boo
with
boo = __import__('boo')
(__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 adding import foo
somewhere within that file. You can get around it by doing this in bar.py
:
import foo
import boo
boo.foo = foo
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)