@@ -5,18 +5,16 @@
|
|||||||
----------
|
----------
|
||||||
问题
|
问题
|
||||||
----------
|
----------
|
||||||
You have code organized as a package and want to import a submodule from one of the
|
将代码组织成包,想用import语句从另一个包名没有硬编码过的包的中导入子模块。
|
||||||
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
|
举个例子,假设在你的文件系统上有mypackage包,组织如下:
|
||||||
on the filesystem:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
@@ -30,32 +28,31 @@ on the filesystem:
|
|||||||
__init__.py
|
__init__.py
|
||||||
bar.py
|
bar.py
|
||||||
|
|
||||||
If the module mypackage.A.spam wants to import the module grok located in the same
|
如果模块mypackage.A.spam要导入同目录下的模块grok,它应该包括的import语句如下:
|
||||||
directory, it should include an import statement like this:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# mypackage/A/spam.py
|
# mypackage/A/spam.py
|
||||||
from . import grok
|
from . import grok
|
||||||
|
|
||||||
If the same module wants to import the module B.bar located in a different directory,
|
如果模块mypackage.A.spam要导入不同目录下的模块B.bar,它应该使用的import语句如下:
|
||||||
it can use an import statement like this:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
# mypackage/A/spam.py
|
# mypackage/A/spam.py
|
||||||
from ..B import bar
|
from ..B import bar
|
||||||
|
|
||||||
Both of the import statements shown operate relative to the location of the spam.py file
|
两个import语句都没包含顶层包名,而是使用了spam.py的相对路径。
|
||||||
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
|
.. code-block:: python
|
||||||
|
|
||||||
@@ -64,47 +61,35 @@ specified absolute names or a relative imports using the syntax shown. For examp
|
|||||||
from . import grok # OK
|
from . import grok # OK
|
||||||
import grok # Error (not found)
|
import grok # Error (not found)
|
||||||
|
|
||||||
The downside of using an absolute name, such as mypackage.A, is that it hardcodes the
|
像mypackage.A这样使用绝对路径名的不利之处是这将顶层包名硬编码到你的源码中。如果你想重新组织它,你的代码将更脆,很难工作。 举个例子,如果你改变了包名,你就必须检查所有文件来修正源码。 同样,硬编码的名称会使移动代码变得困难。举个例子,也许有人想安装两个不同版本的软件包,只通过名称区分它们。 如果使用相对导入,那一切都ok,然而使用绝对路径名很可能会出问题。
|
||||||
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
|
import语句的 ``.`` 和 ``..``看起来很滑稽, 但它指定目录名.为当前目录,..B为目录../B。这种语法只适用于import。
|
||||||
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
|
.. code-block:: python
|
||||||
|
|
||||||
from . import grok # OK
|
from . import grok # OK
|
||||||
import .grok # ERROR
|
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 won’t work if parts of a package are executed directly
|
例如:
|
||||||
as a script. For example:
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
% python3 mypackage/A/spam.py # Relative imports fail
|
% python3 mypackage/A/spam.py # Relative imports fail
|
||||||
|
|
||||||
On the other hand, if you execute the preceding script using the -m option to Python,
|
另一方面,如果你使用Python的-m选项来执行先前的脚本,相对导入将会正确运行。
|
||||||
the relative imports will work properly. For example:
|
例如:
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
% python3 -m mypackage.A.spam # Relative imports work
|
% python3 -m mypackage.A.spam # Relative imports work
|
||||||
|
|
||||||
For more background on relative package imports,
|
更多的包的相对导入的背景知识,请看 `PEP 328 <http://www.python.org/dev/peps/pep-0328>`_ .
|
||||||
see `PEP 328 <http://www.python.org/dev/peps/pep-0328>`_ .
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user