首先明确,Python相对导入只能在同一package下而言的。
项目结构:
relativeimport
├── __init__.py
├── modfail2.py
├── pack1
│ ├── __init__.py
│ ├── mod1.py
│ ├── mod1_1.py
│ ├── pack2
│ │ ├── __init__.py
│ │ └── mod2.py
│ └── pack3
│ ├── __init__.py
│ └── mod3.py
├── packfail
│ ├── __init__.py
│ └── modfail.py
└── server.py
server.py文件
#server.py
import sys
print(sys.path)
from pack1.mod1 import func1
from pack1.mod1_1 import func1_1
from pack1.pack2.mod2 import func2
from packfail.modfail import funcfail
func1()
func1_1()
func2()
modfail.py文件
#modfail.py
from ..pack1.mod1 import func1
def funcfail():
print('funcfail')
server.py是根目下的主文件,运行报错,modfail.py导入顶层目录relativeimport下的mod1模块的func1函数失败:
Traceback (most recent call last):
File "/relativeimport/server.py", line 4, in
from packfail.modfail import funcfail
File "/relativeimport/packfail/modfail.py", line 1, in
from ..pack1.mod1 import func1
ValueError: attempted relative import beyond top-level package
失败原因:
attempted relative import beyond top-level package(超出了顶层package进行相对导入)
但是relativeimport目录下有__init__.py文件的,按理说也应该被当成package的,但是Python貌似有个坑爹的设定,当前目录不会被当做package(也就是server.py所在的relativeimport目录),所以自然就不能进行相对导入了。
改一下server.py文件
import sys
print(sys.path)
from pack1.mod1 import func1
from pack1.mod1_1 import func1_1
from pack1.pack2.mod2 import func2
from .modfail2 import funcfail2
func1()
func1_1()
func2()
Traceback (most recent call last):
File "/relativeimport/server.py", line 9, in
from .modfail2 import funcfail2
ModuleNotFoundError: No module named '__main__.modfail2'; '__main__' is not a package
相对导入 relativeimport目录下的modfail2.py模块的funcfail2失败,说是'__main__' is not a package,就是当前的relativeimport目录就不是一个package,就是Python的那个坑爹设定,不会把项目入口的当前目录当做package。
改成绝对导入一起正常。
modfail.py
#modfail.py
# from ..pack1.mod1 import func1 #相对导入错误
from pack1.mod1 import func1 #绝对导入正确
def funcfail():
print('funcfail')
#server.py
#server.py
import sys
print(sys.path)
from pack1.mod1 import func1
from pack1.mod1_1 import func1_1
from pack1.pack2.mod2 import func2
from packfail.modfail import funcfail
# from .modfail2 import funcfail2 #相对导入错误
from modfail2 import funcfail2 #绝对导入正确
func1()
func1_1()
func2()
funcfail()
funcfail2()
要用相对导入必须要统一package中。pack1下就是相对导入的例子,一切正常木有错误:
pack1结构:
mod2.py
#mod2.py
from ..mod1_1 import func1_1
from ..pack3.mod3 import func3
def func2():
print('func2')
mod3.py
#mod3.py
def func3():
print('func3')
mod1.py
#mod1.py
from .mod1_1 import func1_1
def func1():
print('func1')
mod1_1.py
#mod1_1.py
def func1_1():
print('func1_1')
全部正确输出:
func1
func1_1
func2
funcfail
funcfail2