首先明确,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 <module>
    from packfail.modfail import funcfail
  File "/relativeimport/packfail/modfail.py", line 1, in <module>
    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 <module>
    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

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐