[英]How can I fix these relative import error
我有這樣的文件夾結構,每次嘗試使用相對導入時,都會引發錯誤
├── graphics
│ ├── __init__.py
│ ├── A
│ │ ├── __init__.py
│ │ ├── grok.py
│ │ └── spam.py
└── B
├── __init__.py
└── bar.py
spam.py/
def func():
pass
bar.py/
def f():
pass
所有這些代碼都在grok.py中進行了測試:
from . import spam
# ImportError: cannot import name 'spam'
from .spam import func
# ModuleNotFoundError: No module named '__main__.spam'; '__main__'
is not a package
from ..B import bar
# ValueError: attempted relative import beyond top-level package
以下代碼均不會導致任何錯誤:
from graphics.A import spam
from graphics.A.spam import func
from graphics.B import bar
from graphics.B.bar import f
我假設當您說“ 在grok.py中測試 ”時,您正在像這樣運行它:
python3 graphics/A/grok.py
python3 A/grok.py
python3 grok.py
從Python關於Packages和Package-In-Package引用的文檔中 ,有一條注釋指出:
請注意,相對導入基於當前模塊的名稱。 由於主模塊的名稱始終為“
__main__
”,因此用作Python應用程序主模塊的模塊 必須始終使用絕對導入 。
當您運行grok.py
,它將被視為主模塊,並且只有在您使用絕對導入的情況下,導入才起作用(假設您未對sys.path
進行任何更改,我們將在以后進行介紹)。 您可以通過將print(__name__)
放在print(__name__)
的開頭來進行測試,這將打印出“ __main__
”。
如果在調用grok
模塊的圖形包下有一個單獨的python文件(例如main.py
),則相對導入實際上將起作用。
├── graphics
│ ├── __init__.py
| ├── main.py <<---- add this
│ ├── A
│ ├── B
在main.py
,讓我們只導入grok
模塊:
from A import grok
在grok.py
,讓我們測試相對導入:
from . import spam
spam.spam_func()
from .spam import spam_func
spam_func()
from B import bar
bar.bar_func()
在spam.py
:
def spam_func():
print("spammy")
在bar.py
:
def bar_func():
print("barry")
當您運行main.py
:
graphics$ python3 main.py
spammy
spammy
barry
您不會遇到任何先前的錯誤。 相對進口工作。 注意,要從B
導入,我from B
而不是from ..B
。 這是因為導入路徑是從main.py
的角度來看的。 您可以通過在main.py
頂部添加以下內容來進行測試:
import sys
print(sys.path)
# prints a list, ['/path/to/graphics/',...]
如果您from ..B
,則意味着/path/to/graphics/../
當然沒有B
模塊(因此,您將收到“ 嘗試在頂級軟件包之外進行相對導入 ”錯誤)
現在,假設您不想使用單獨的main.py
,而是要直接運行grok.py
您可以手動將graphics
包的路徑添加到sys.path
。 然后,您可以from A
grok.py
from A
和from B
中進行grok.py
。
import sys
sys.path.append("/full/path/to/graphics/")
from A import spam
spam.spam_func()
from B import bar
bar.bar_func()
如果您想“入侵” sys.path
,建議您閱讀更多有關sys.path
並查看其他相關文章,以討論向sys.path
添加路徑的sys.path
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.