Bootstrap

python代码中 from . import ××× 是什么意思?

sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
               
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py

从当前文件夹导入
from . import echo

在当前文件夹effects里的__init__.py程序中导入echo子模块。

从上一级文件夹导入
from … import formats

在上一级文件夹sound里的__init__.py程序中导入formats。

从上一级文件夹sound下的filters文件夹里的__init__.py导入
from …filters import equalizer

在上一级文件夹sound下的filters文件夹里的__init__.py程序中导入equalizer子模块。

包内的文件相互导入分两种,用绝对路径和相对路径,用.或者..都是第二种,相对路径。

重点是,相对导入的路径依赖于当前模块的_name_,是根据它的“值”去找平级或者上级文件。

假设该from . import x语句存在于proj/test.py中,它会导入同级目录下的__init__.py即proj/__init__.py中的x对象,如果没有proj/__init__.py或有那个文件但是文件中不存在x对象,就导入proj/x/__init__.py,如果还没有,就导入proj/x.py,还没有就报错。

其中同级是按__name__的前一部分或 __package__ 确定的。如果用python proj/test.py运行,__name__就是__main__,__package__是None,就会报错。如果用python -m proj.test运行,虽然__name__还是__main__,但是__package__是proj,就能成功导入,即使proj/__init__.py不存在也行。

例如:在模块A.B.C中的代码:

from . import D     # 导入A.B.D
from .. import E    # 导入A.E
from ..F import G    # 导入A.F.G,.. 和 F是连着的,中间没有空格
.代表当前目录,..代表上一层目录,...代表上上层目录。

回到遇到的问题,答案其实很简单:

from . import XXX是在当前程序所在文件夹里的__init__.py中导入XXX

如果当前程序所在文件夹里没有__init__.py文件的话,就不能这样写,而应该写成from .A import XXX,A是指当前文件夹下你想导入的函数(或者其它的)的python程序名

如果你想导入的函数不在当前文件夹,那么就有可能用到 from .. import XXX(即上一个文件夹中的__init__.py),或者from ..A import XXX(即上一个文件夹中的文件A)

;