import X between submodules in a package

D

Donn Ingle

Hi, I'm sure this is a FAQ, but I have just not found clarity on the
web/docs.

(using monospaced type to show the tree)
trunk:$ tree
..
fp
|-- fontypython
| |-- __init__.py
| |-- cli.py
| |-- config.py

(I start it all with ./fp)

fp says:
import cli

cli.py says:
import os
import config

config.py says:
print os.environ['HOME']

I get a NameError in config.py

If I add 'import os' to config.py all is well.

So, I guess I am confused about the 'scope' of what gets imported where. I
am thinking that if one module (py file) does *import os* something and
*then* imports another module - the second module should have access to os
too?
I imagine myself "standing" inside cli.py at this point and saying "well I
can see os, and I'm bringing config *into* this space, so they should be
able to see os too."

How do I structure things so that I don't have endless repetitions of import
in every py file within my package directory?

\d
 
B

Bruno Desthuilliers

Donn Ingle a écrit :
Hi, I'm sure this is a FAQ, but I have just not found clarity on the
web/docs.

(using monospaced type to show the tree)
trunk:$ tree
.
fp
|-- fontypython
| |-- __init__.py
| |-- cli.py
| |-- config.py

(I start it all with ./fp)

fp says:
import cli

cli.py says:
import os
import config

config.py says:
print os.environ['HOME']

I get a NameError in config.py

If I add 'import os' to config.py all is well.

So, I guess I am confused about the 'scope' of what gets imported where. I
am thinking that if one module (py file) does *import os* something and
*then* imports another module - the second module should have access to os
too?

Definitively no. This would make the second module dependent on the
context in which it is used, which would be a VeryBadThing(tm). Each
Python module is it's own _distinct_ namespace, and only depend on the
name it explicitely imports or defines. FWIW, it's the whole point of
*modules* (by opposition to 'includes' à la PHP).
I imagine myself "standing" inside cli.py at this point and saying "well I
can see os, and I'm bringing config *into* this space, so they should be
able to see os too."

I can tell you from experience (with languages that work that way, cf
above) that this usually leads to the worst possible mess, even if
you're being careful.
How do I structure things so that I don't have endless repetitions of import
in every py file within my package directory?

Having explicits imports in each module is good wrt/ readability. Now if
you have a huge common set of imports in each and every submodule of a
package, you can of course factor them out in a distinct submodule and
just do a 'from myimports import *' at the top of the others submodules...
 
C

Chris

So, I guess I am confused about the 'scope' of what gets imported where. I
am thinking that if one module (py file) does *import os* something and
*then* imports another module - the second module should have access to os
too?
I imagine myself "standing" inside cli.py at this point and saying "well I
can see os, and I'm bringing config *into* this space, so they should be
able to see os too."

Each module has its own namespace. Why config throws an error is
because even though you imported 'os' in the cli module you are
calling an os function from a different module. You can however put
them all together in a different manner if this helps:

#fp.py
import cli

#cli.py
import os

#config.py
import cli
print cli.os.environ['HOME']

if you wish to use the os module loaded by the cli module
 
D

Donn Ingle

would be a VeryBadThing(tm).
:)
Having explicits imports in each module is good wrt/ readability.
Okay, I can accept that. I worry that it's opening the module file over and
over again - or does it open it once and kind of re-point to it when it
hits a second import of the same thing?
package, you can of course factor them out in a distinct submodule and
just do a 'from myimports import *' at the top of the others submodules...
Good point.

\d
 
B

Bruno Desthuilliers

Donn Ingle a écrit :
Okay, I can accept that. I worry that it's opening the module file over and
over again

Hopefully not ! "import" is not "include".
- or does it open it once and kind of re-point to it when it
hits a second import of the same thing?

You guess. When fisrt imported, the module's source is executed, a
module object is created and stored in sys.modules, and the needed names
are inserted into the importing module's namespace. Next times the
module is "served" directly from sys.modules.
Good point.

Note that while it's perfectly legal, that's a pattern I'd try to avoid
unless I have a very good reason to use it.
 
D

Donn Ingle

You guess. When fisrt imported, the module's source is executed, a
module object is created and stored in sys.modules, and the needed names
are inserted into the importing module's namespace. Next times the
module is "served" directly from sys.modules.

Peachy, thanks.

\d
 
G

Gabriel Genellina

#fp.py
import cli

#cli.py
import os

#config.py
import cli
print cli.os.environ['HOME']

if you wish to use the os module loaded by the cli module

Chris said:
print cli.os.environ['HOME']
I was really confused by your reply until I saw the cli.os part. Okay, I
see
what you mean.

Note that altough this is perfectly legal, I would *not* recommend doing
it unless you have a compelling reason to do so (like providing a single
public namespace for a package, for example).
Some people choose to remove spurious names, to keep the namespace clean
if that's important for other usage:

# config.py
import os, sys
startup_dir = os.path.abspath(os.path.dirname(sys.argv[0]))
del os, sys
background_color = "white"
....

# main.py
import config
for key, value in vars(config).iteritems():
print '%s=%r' % (key, value)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top