程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> Python包的相對導入時出現“ ‘Parent module not loaded, cannot perform relative import”的解決方法

Python包的相對導入時出現“ ‘Parent module not loaded, cannot perform relative import”的解決方法

編輯:Python

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

from . import XXX

  或者 

from .. import XXX

  時會遇到這樣兩個錯誤:

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

  和

ValueError: attempted relative import beyond top-level package

 

  其實這兩個錯誤的原因歸根結底是一樣的:在涉及到相對導入時,package所對應的文件夾必須正確的被python解釋器視作package,而不是普通文件夾。否則由於不被視作package,無法利用package之間的嵌套關系實現python中包的相對導入。

  文件夾被python解釋器視作package需要滿足兩個條件:

  1、文件夾中必須有__init__.py文件,該文件可以為空,但必須存在該文件。

  2、不能作為頂層模塊來執行該文件夾中的py文件(即不能作為主函數的入口)。

  補充:在"from YY import XX"這樣的代碼中,無論是XX還是YY,只要被python解釋器視作package,就會首先調用該package的__init__.py文件。如果都是package,則調用順序是YY,XX。

  另外,練習中“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 <module>
from cat import cat
File "D:\PythonLearning\TestIm2\cat\cat.py", line 4, in <module>
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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved