ValueError: attempted relative import beyond top-level package
假设有如下层次包目录
1 project/ 2 __init__.py 3 mypackage/ 4 __init__.py 5 A/ 6 __init__.py 7 spam.py #* print("In spam") *# 8 grok.py #* print("In grok") *# 9 C/ 10 __init__.py 11 hello.py #* print("In hello") *# 12 B/ 13 __init__.py 14 bar.py #* print("In bar") *# 15 run.py 16 main.py
相对导入语法
from . importmodule from .. importmodule from ... import module
- run.py作为顶层模块执行导入A.spam时
- run.py的__name__等于 __main__
- spam.py的__name__等于 A.spam
- A成为顶层的包,所以相对导入最多只能访问到A,A之外的层次结构是不可见的
- main.py作为顶层模块执行导入mypackage.A.spam是
- main.py的 __name__为 __main__
- spam.py的__name__为mypackage.A.spam
- mypackage成为顶层包,相对导入作用域扩大,B/包对spam.py可见
- 如果将run.py当作顶层执行模块
- A/和 B/ 将成为toplevelpackage顶层包A/中的模块不能用相对导入来导入B/包中的模块,因为不能越过顶层包。
- A/、B/包中的目录可以导入本包中及以下的模块
- 如果将main.py当作顶层执行模块
- mypackage/成为顶层包,A/可以访问到B/包,不会出现ValueError: attempted relative import beyond top-level package
例子
## run.py (run.py当作顶层执行模块,即 python run.py) #----------- importA.spam ## spam.py #-------------- from . import grok #ok from .C import hello #ok from ..B import bar #!Err ##—— ValueError: attempted relative import beyond top-level package print('In spam') ## main.py #------------ importmypackage.A.spam ## spam.py #------------- from ..B import bar #ok print('In spam')