Import Problems
Robert Kern
robert.kern at gmail.com
Fri Apr 27 16:09:29 EDT 2007
Bill Jackson wrote:
> Once again, I am having issues with imports...
>
> Until now, I thought the general guidelines were to rarely use 'from x
> import y' syntax, except when you really want to copy names over.
No, the guideline is to not use "from x import *" except at the interactive
prompt and occasionally in __init__.py's to "copy names over" as you put it.
> However, I have run into issues by following this guideline. So...
>
> 1) What is going wrong in the example below?
> 2) What is a good way to handle imports for packages w/subdirectories?
>
> Here is a sample directory structure:
>
> importtest/
> __init__.py
> test2/
> __init__.py
> someclass.py
> mytest.py
>
>
> Here are the definitions of the files:
>
> # importtest/__init__.py
> from test2 import *
>
> # importtest/test2/__init__.py
> from someclass import *
> from test2 import *
>
> # importtest/test2/someclass.py
> class SomeClass:
> pass
>
> # importtest/test2/mytest.py
> import importtest
> print importtest.SomeClass
>
>
> On import I get the following:
>
> >>> import importtest
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "/home/user/lib/python/importtest/__init__.py", line 1, in ?
> from test2 import *
> File "/home/user/lib/python/importtest/test2/__init__.py", line 2, in ?
> from mytest import *
> File "/home/user/lib/python/importtest/test2/mytest.py", line 3, in ?
> print importtest.SomeClass
> AttributeError: 'module' object has no attribute 'SomeClass'
> >>>
>
>
> The problem seems to be an 'order' issue. importtest/test2/__init__.py
> has loaded someclass.py, but it doesn't seem to have copied its contents
> into importtest/__init__.py....perhaps it is because it hasn't finished
> all of its imports. Is this correct?
You are right that it is an order issue. The line "from test2 import *" hasn't
finished executing by the time "print importtest.SomeClass" is executed because
the former is trying to execute the latter.
> So what is a good way to deal with this? In files which contain
> implementations, I thought it was best not to use 'from x import y', but
> this seems to be the only way to get this to work:
My recommendation is that inside packages, be as specific as is feasible with
your imports, even if you expose the symbols at a higher level for external
callers. If you have a module whose contents are being exposed in your
__init__.py, never rely on the contents of that __init__.py in that code.
Instead, go straight to the real modules that implement the symbols that you
need. So mytest.py should read:
from importtest.test2.someclass import SomeClass
print SomeClass
or
from importtest.test2 import someclass
print someclass.SomeClass
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
More information about the Python-list
mailing list