參考來源:https://www.cnblogs.com/ArsenalfanInECNU/p/5346751.html
在導(dǎo)入python的package時,使用 . 或者 .. 來代表當(dāng)前文件夾和上層文件夾的形式為相對導(dǎo)入渊啰。例如,【from . import foo】【from .. import foo】
在執(zhí)行python的相對導(dǎo)入時资柔,可能會拋出如下的錯誤:
【SystemError: Parent module''notloaded, cannot perform relativeimport】
和
【ValueError: attempted relativeimportbeyond top-level package】
其實這兩個錯誤的原因歸根結(jié)底是一樣的:在涉及到相對導(dǎo)入時,package所對應(yīng)的文件夾必須正確的被python解釋器視作package撵割,而不是普通文件夾贿堰。否則由于不被視作package,無法利用package之間的嵌套關(guān)系實現(xiàn)python中包的相對導(dǎo)入啡彬。
文件夾被python解釋器視作package需要滿足兩個條件:
1羹与、文件夾中必須有__init__.py文件,該文件可以為空庶灿,但必須存在該文件注簿。
2、不能作為頂層模塊來執(zhí)行該文件夾中的py文件(即不能作為主函數(shù)的入口)跳仿。
例:有如下的文件目錄樹:
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
結(jié)果:
I'm Tom's__init__!
I'm Tom's Brother!
Traceback (most recent call last):
File "D:\PythonLearning\TestIm2\main.py", line 3,infromcatimport cat
File "D:\PythonLearning\TestIm2\cat\cat.py", line 4,infrom..import dog
ValueError: attempted relative importbeyond top-level package
>>>
可以看到
from .? import tomBrother 是可以被執(zhí)行的,而from .. import?Kate 會報錯捐晶,這是因為我們是在TestIm文件夾下把main.py文件作為主函數(shù)的入口執(zhí)行的菲语,因此盡管TestIm文件夾中有__init__.py文件妄辩,但是該文件夾不能被python解釋器視作package,即Tom package不存在上層packge山上,自然會報錯眼耀,相對導(dǎo)入時超出了最高層級的package。
解決辦法:新建文件夾testImPack, 將除了main.py 的其他模塊和包全部移入testImPack中佩憾。
修改后的目錄樹如下:
testIm/
--main.py : from testIm.Tom import tom
--testImPack/
--__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
補充:在"from YY import XX"這樣的代碼中哮伟,無論是XX還是YY,只要被python解釋器視作package妄帘,就會首先調(diào)用該package的__init__.py文件楞黄。如果都是package,則調(diào)用順序是YY抡驼,XX鬼廓。