[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

import X between submodules in a package

donn

12/19/2007 7:24:00 AM

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


7 Answers

Bruno Desthuilliers

12/19/2007 8:46:00 AM

0

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...

Chris

12/19/2007 10:02:00 AM

0

On Dec 19, 9:24 am, Donn Ingle <donn.in...@gmail.com> wrote:
> 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

donn

12/19/2007 12:40:00 PM

0

> 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

donn

12/19/2007 12:43:00 PM

0

Chris wrote:
> 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.

\d

Bruno Desthuilliers

12/19/2007 12:59:00 PM

0

Donn Ingle a écrit :
>> 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

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.

>
>> 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.

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.


donn

12/19/2007 3:43:00 PM

0

> 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

Gabriel Genellina

12/19/2007 5:51:00 PM

0

En Wed, 19 Dec 2007 07:02:00 -0300, Chris <cwitts@gmail.com> escribió:

> #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

En Wed, 19 Dec 2007 09:42:31 -0300, Donn Ingle <donn.ingle@gmail.com>
escribió:

> Chris wrote:
>> 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)

--
Gabriel Genellina