假設有如下層次包目錄
project
/
__init__
.
py
mypackage
/
__init__
.
py
A
/
__init__
.
py
spam
.
py
#* print("In spam") *#
grok
.
py
#* print("In grok") *#
C
/
__init__
.
py
hello
.
py
#* print("In hello") *#
B
/
__init__
.
py
bar
.
py
#* print("In bar") *#
run
.
py
main
.
py
相對導入語法
from
.
import
module
from
..
import
module
from
...
import
module
相對導入與模塊__name__有關
- 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/ 將成為 toplevel package 頂層包 A/中的模塊不能用相對導入來導入B/包中的模塊,因為不能越過頂層包。
-
A/、B/ 包中的目錄可以導入本包中及以下的模塊
-
如果將main.py當作頂層執行模塊
-
mypackage/成為頂層包,A/可以訪問到B/包,不會出現 ValueError: attempted relative import beyond top-level package
例子
'''run.py
import A.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
import mypackage.A.spam
'''
-----------------------------------
'''spam.py
from ..B import bar # ok
print('In spam')
'''