包内的文件相互导入分两种,用绝对路径和相对路径,用.或者..都是第二种,相对路径。
重点是,相对导入的路径依赖于当前模块的_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)