Files
python3-cookbook/source/c10/p03_import_submodules_by_relative_names.rst
2015-04-28 15:13:01 +08:00

111 lines
3.6 KiB
ReStructuredText
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

============================
10.3 使用相对路径名导入包中子模块
============================
----------
问题
----------
You have code organized as a package and want to import a submodule from one of the
other package submodules without hardcoding the package name into the import
statement.
|
----------
解决方案
----------
To import modules of a package from other modules in the same package, use a packagerelative
import. For example, suppose you have a package mypackage organized as follows
on the filesystem:
.. code-block:: python
mypackage/
__init__.py
A/
__init__.py
spam.py
grok.py
B/
__init__.py
bar.py
If the module mypackage.A.spam wants to import the module grok located in the same
directory, it should include an import statement like this:
.. code-block:: python
# mypackage/A/spam.py
from . import grok
If the same module wants to import the module B.bar located in a different directory,
it can use an import statement like this:
.. code-block:: python
# mypackage/A/spam.py
from ..B import bar
Both of the import statements shown operate relative to the location of the spam.py file
and do not include the top-level package name.
|
----------
讨论
----------
Inside packages, imports involving modules in the same package can either use fully
specified absolute names or a relative imports using the syntax shown. For example:
.. code-block:: python
# mypackage/A/spam.py
from mypackage.A import grok # OK
from . import grok # OK
import grok # Error (not found)
The downside of using an absolute name, such as mypackage.A, is that it hardcodes the
top-level package name into your source code. This, in turn, makes your code more
brittle and hard to work with if you ever want to reorganize it. For example, if you ever
changed the name of the package, you would have to go through all of your files and fix
the source code. Similarly, hardcoded names make it difficult for someone else to move
the code around. For example, perhaps someone wants to install two different versions
of a package, differentiating them only by name. If relative imports are used, it would
all work fine, whereas everything would break with absolute names.
The ``.`` and ``..`` syntax on the import statement might look funny, but think of it as specifying
a directory name. . means look in the current directory and ..B means look in
the ../B directory. This syntax only works with the from form of import. For example:
.. code-block:: python
from . import grok # OK
import .grok # ERROR
Although it looks like you could navigate the filesystem using a relative import, they are
not allowed to escape the directory in which a package is defined. That is, combinations
of dotted name patterns that would cause an import to occur from a non-package directory
cause an error.
Finally, it should be noted that relative imports only work for modules that are located
inside a proper package. In particular, they do not work inside simple modules located
at the top level of scripts. They also wont work if parts of a package are executed directly
as a script. For example:
.. code-block:: python
% python3 mypackage/A/spam.py # Relative imports fail
On the other hand, if you execute the preceding script using the -m option to Python,
the relative imports will work properly. For example:
.. code-block:: python
% python3 -m mypackage.A.spam # Relative imports work
For more background on relative package imports,
see `PEP 328 <http://www.python.org/dev/peps/pep-0328>`_ .