Python包的相對導入時出現錯誤的解決方法

在練習Python中package的相對導入時,即python

from . import XXX
  或者 linux

from .. import XXX
  時會遇到這樣兩個錯誤:shell

SystemError: Parent module '' not loaded, cannot perform relative import
  和函數

ValueError: attempted relative import beyond top-level packageorm

  其實這兩個錯誤的緣由歸根結底是同樣的:在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視做package,而不是普通文件夾。不然因爲不被視做package,沒法利用package之間的嵌套關係實現python中包的相對導入。it

  文件夾被python解釋器視做package須要知足兩個條件:ast

  一、文件夾中必須有__init__.py文件,該文件能夠爲空,但必須存在該文件。form

  二、不能做爲頂層模塊來執行該文件夾中的py文件(即不能做爲主函數的入口)。test

  補充:在"from YY import XX"這樣的代碼中,不管是XX仍是YY,只要被python解釋器視做package,就會首先調用該package的__init__.py文件。若是都是package,則調用順序是YY,XX。import

  另外,練習中「from . import XXX」和「from .. import XXX」中的'.'和'..',能夠等同於linux裏的shell中'.'和'..'的做用,表示當前工做目錄的package和上一級的package。

  舉個例子:

  目錄樹

  testIm/

  --init.py

  --main.py : from Tom import tom

  --Tom/

    --init.py : print("I'm Tom's init!")

    --tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")

    --tomBrother.py print(I'm Tom's Brother!)

  --Kate/

    --init.py : print("I'm Kate's init!")

    --kate.py

  運行文件:main.py

  結果:

複製代碼
I'm Tom's init!
I'm Tom's Brother!
Traceback (most recent call last):
File "D:\PythonLearning\TestIm2\main.py", line 3, in
from cat import cat
File "D:\PythonLearning\TestIm2\cat\cat.py", line 4, in
from .. import dog
ValueError: attempted relative import beyond top-level package

複製代碼
能夠看到from . import tomBrother順利執行,首先執行了Tom文件夾下的__init__.py文件,後來執行了tomBrother.py文件,可是當執行到「from .. import dog」時報錯,這是由於咱們是在TestIm文件夾下把main.py文件做爲主函數的入口執行的,所以儘管TestIm文件夾中有__init__.py文件,可是該文件夾不能被python解釋器視做package,即Tom package不存在上層packge,天然會報錯,相對導入時超出了最高層級的package。

修改方法:

目錄樹

  test/

  --main.py : from testIm.Tom import tom

  --testIm/

    --init.py

    --Tom/

      --init.py : print("I'm Tom's init!")

      --tom.py : from . import tomBrother, from .. import Kate,print("I'm Tom!")

      --tomBrother.py print(I'm Tom's Brother!)

    --Kate/

    --init.py : print("I'm Kate's init!")

    --kate.py

  運行文件:main.py

結果:  

I'm top's init!
I'm Tom's init!
I'm Tom's Brother!!
I'm Kate's init! I'm Tom! 即主函數入口不在TestIm中,則TestIm和其一樣包含__init__.py文件的子文件夾都被python解釋器視做package,造成相應的嵌套關係。能夠正常使用from . import XXX和from .. import XXX。

相關文章
相關標籤/搜索