[Tutor] relative imports within a package?
Steven D'Aprano
steve at pearwood.info
Sat Nov 7 20:17:12 EST 2015
On Sat, Nov 07, 2015 at 04:09:19PM -0600, James Hartley wrote:
> The Python 3 tutorial discusses relative imports at:
>
> https://docs.python.org/3/tutorial/modules.html#intra-package-references
>
> I have the following directory structure for a package in development:
>
> + outer_package/
> + __init__.py
> + inner_package
> | + __init__.py
> | + myclass.py
> + collateral_directory
> + arbitrary_tool.py
As shown above, "collateral_directory" is not part of the package. It is
just a directory with stuff in it. The fact that the "stuff" happens to
include a Python script is irrelevant.
If "arbitrary_tool.py" is actually independent of outer_package, you
should have this layout:
+ arbitrary_tool.py
+ outer_package/
+ __init__.py
+ inner_package
| + __init__.py
| + myclass.py
where the enclosing directory is part of your PYTHONPATH. Then, in
arbitrary_tool, you say:
from outer_package import MyClass
# assuming outer_package has already made this available
or
from outer_package.inner_packages import MyClass
# assuming inner_package has made this available
# which you have done
or
from outer_package.inner_package.myclass import MyClass
whichever you prefer.
If arbitrary_tool is not independent of outer_package, then you should
convert it to a package with this layout:
+ outer_package/
+ __init__.py
+ inner_package
| + __init__.py
| + myclass.py
+ collateral_directory
+ __init__.py
+ arbitrary_tool.py
__init__.py may be an empty file, it just has to exist. Now
collateral_directory is a sub-package, and you can do things like this:
# from outer_package.__init__
import collateral_directory.arbitrary_tool
# from inner_package.myclass (but watch out for circular imports)
from ..collateral_directory.arbitrary_tool import Spam
But if arbitrary_tool is part of the package, and it is the only file in
collateral_directory, why mess about with a subpackage? Lay your package
out like this:
+ outer_package/
+ __init__.py
+ arbitrary_tool.py
+ inner_package
| + __init__.py
| + myclass.py
and inside arbitrary_tool say:
from inner_package.myclass import MyClass
(P.S. this is Python, not Java. There is no requirement to put every
class in its own file, in fact doing so is mildly discouraged. Does
MyClass truly deserve its own file? If not, you may be able to simplify
your package structure even more.)
--
Steve
More information about the Tutor
mailing list