Python 相對導入attempted relative import beyond top-level package


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 . 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 (run.py當作頂層執行模塊,即 python 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')
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM