[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.python

confusion about package/module imports

Jugdish

1/1/2008 8:27:00 PM

Why doesn't the following work?

>>> ls $HOME
$HOME/pkg/__init__.py
$HOME/pkg/subpkg/__init__.py
$HOME/pkg/subpkg/a.py
$HOME/pkg/subpkg/b.py

>>> cat $HOME/pkg/__init__.py
# empty

>>> cat $HOME/pkg/subpkg/__init__.py
import a
import b

>>> cat $HOME/pkg/subpkg/a.py
class A:
pass

>>> cat $HOME/pkg/subpkg/b.py
import pkg.subpkg.a
class B(pkg.subpkg.a.A):
pass

>>> setenv PYTHONPATH $HOME:$PYTHONPATH
>>> python $HOME/pkg/subpkg/b.py
Traceback (most recent call last):
File "pkg/subpkg/b.py", line 1, in ?
import pkg.subpkg.a
File "$HOME/pkg/subpkg/__init__.py", line 2, in ?
import b
File "$HOME/pkg/subpkg/b.py", line 2, in ?
class B(pkg.subpkg.a.A):
AttributeError: 'module' object has no attribute 'subpkg'
3 Answers

Scott David Daniels

1/1/2008 9:35:00 PM

0

Jugdish wrote:
> Why doesn't the following work?
> ...
[well boiled-down code skipped]
>>>> setenv PYTHONPATH $HOME:$PYTHONPATH
>>>> python $HOME/pkg/subpkg/b.py
> Traceback (most recent call last):
> File "pkg/subpkg/b.py", line 1, in ?
> import pkg.subpkg.a
> File "$HOME/pkg/subpkg/__init__.py", line 2, in ?
> import b
> File "$HOME/pkg/subpkg/b.py", line 2, in ?
> class B(pkg.subpkg.a.A):
> AttributeError: 'module' object has no attribute 'subpkg'

OK, here's a trick for finding import problems:
python -v <file to fiddle>
(shows all imports)

And for this case:
sprinkle prints to find out what is happening.

so, add "print __name, __file__" to the top of each file where
you wonder what is going on.
I later added prints in pkg/subpkg/__init__.py to make the steps clear.

You'll see that b is executed (making module __main__),
it imports pkg.subpkg.a,
which is accomplished by importing pkg (successfully),
then by importing pkg.subpkg
which imports pkg.subpkg.a (successfully)
and then imports pkg.subpkg.b
which then attempts to import pkg.subpkg.a
At that point, only the module pkg
and what should eventually become pkg.subpkg.a
have been successfully imported. pkg.subpkg had not yet been imported.
If you remove the "import b" from subpkg's __init__, you will find
your problems going away.
Alternatively, you can remove the import a / import b from subpkg
and add import subpkg.a, subpkg.b to pkg's __init__. Essentially,
you need pkg.subpkg fully imported before you import pkg.subpkg.b

Of course, in most of these cases you will have imported the code
for b twice, once as a main program, and once as a module in the
hierarchy, which is probably your actual problem (and why I use
"print __name__, __file__").


--Scott David Daniels
Scott.Daniels@Acm.Org

Jugdish

1/1/2008 10:35:00 PM

0

Thanks very much for your helpful response!

> You'll see that b is executed (making module __main__),
> (1) it imports pkg.subpkg.a,
> (2) which is accomplished by importing pkg (successfully),
> (3) then by importing pkg.subpkg
> (4) which imports pkg.subpkg.a (successfully)
> (5) and then imports pkg.subpkg.b
> (6) which then attempts to import pkg.subpkg.a

What I'm not really understanding here is why this fails at lines (5)
and (6). If pkg.subpkg.a has already been successfully imported at
line (4), then (6) should be detected as a duplicate import and just
be skipped, right? So the import at line (5) should succeed.

Scott David Daniels

1/1/2008 11:17:00 PM

0

Jugdish wrote:
> Thanks very much for your helpful response!
>
>> You'll see that b is executed (making module __main__),
>> (1) it imports pkg.subpkg.a,
>> (2) which is accomplished by importing pkg (successfully),
>> (3) then by importing pkg.subpkg
>> (4) which imports pkg.subpkg.a (successfully)
>> (5) and then imports pkg.subpkg.b
>> (6) which then attempts to import pkg.subpkg.a
>
> What I'm not really understanding here is why this fails at lines (5)
> and (6). If pkg.subpkg.a has already been successfully imported at
> line (4), then (6) should be detected as a duplicate import and just
> be skipped, right? So the import at line (5) should succeed.

I'm sorry, I used shorthand. While a module is being imported,
it only provisionally has a name. Until subpkg is fully imported,
there is no module named pkg.subpkg. At the root level (pkg, for
example), the module is provisionally added. Further down the tree,
the module (such as that for pkg/subpkg/__init__.py) is only added
to the symbol table (the packages __dict__) when the module has been
completely imported.

-Scott