10.3 使用相对路径�导入包中�模�¶

问题¶

将代�组织�包,想用import语�从�一个包�没有硬编�过的包中导入�模�。

解决方案¶

使用包的相对导入,使一个模�导入�一个包的�一个模� 举个例�,�设在你的文件系统上有mypackage包,组织如下:

mypackage/
    __init__.py
    A/
        __init__.py
        spam.py
        grok.py
    B/
        __init__.py
        bar.py

如果模�mypackage.A.spam�导入�目录下的模�grok,它应该包括的import语�如下:

# mypackage/A/spam.py
from . import grok

如果模�mypackage.A.spam�导入��目录下的模�B.bar,它应该使用的import语�如下:

# mypackage/A/spam.py
from ..B import bar

两个import语�都没包�顶层包�,而是使用了spam.py的相对路径。

讨论¶

在包内,既�以使用相对路径也�以使用�对路径�导入。 举个例�:

# mypackage/A/spam.py
from mypackage.A import grok # OK
from . import grok # OK
import grok # Error (not found)

�mypackage.A这样使用�对路径�的�利之处是这将顶层包�硬编�到你的��中。如果你想�新组织它,你的代�将更脆,很难工作。 举个例�,如果你改�了包�,你就必须检查所有文件�修正��。 �样,硬编�的�称会使移动代��得困难。举个例�,也许有人想安装两个��版本的软件包,�通过�称区分它们。 如果使用相对导入,那一切都ok,然而使用�对路径�很�能会出问题。

import语�的 . 和 .. 看起�很滑稽, 但它指定目录�.为当�目录,..B为目录../B。这�语法�适用于import。 举个例�:

from . import grok # OK
import .grok # ERROR

尽管使用相对导入看起��是�览文件系统,但是�能到定义包的目录之外。也就是说,使用点的这�模�从�是包的目录中导入将会引�错误。

最�,相对导入�适用于在�适的包中的模�。尤其是在顶层的脚本的简�模�中,它们将�起作用。如果包的部分被作为脚本直接执行,那它们将�起作用 例如:

% python3 mypackage/A/spam.py # Relative imports fail

�一方�,如果你使用Python的-m选项�执行先�的脚本,相对导入将会正确�行。 例如:

% python3 -m mypackage.A.spam # Relative imports work

更多的包的相对导入的背景知识,请看 PEP 328 .