1.入口文件不能用相對路徑引入模塊和包python
所謂的入口文件,就是你須要執行的腳本文件。編程
文件架構以下:vim
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---index.py ---__init__.py
上面_dir後綴的名字,都是python package模塊名。架構
在如上的文件架構中假設index.py是入口文件,也就是咱們須要執行的腳本,咱們以index.py爲起點,去引入demo.py代碼以下:app
from .tools_dir.demo import func func()
再附上demo文件代碼:ide
def func(): print("hello")
報錯信息以下:spa
Traceback (most recent call last): File "D:/lmj_work_file/lmj/from_dir/from_test/index.py", line 31, in <module> from .tool.xxx import func ModuleNotFoundError: No module named '__main__.tool'; '__main__' is not a package
糾錯以下:命令行
from tool.demo import func func()
只須要把indexx.py文件中的相對引入換成絕對路徑引入便可。code
補充說明另外這裏須要提示一點的是,若是是用pycharm這個ide寫代碼,那麼,pycharm它自己默認的東西仍是比較多的,提供了方便的同時,也提供了限制。好比這裏模塊引入的時候,如上的狀況,咱們糾錯了,用pycharm能夠運行,用命令行也能執行,可是在pycharm裏面,blog
它會飄紅提示,這裏的緣由,我稍微解釋一下,pycharm默認,全部的入口文件都須要放到頂層路徑下,所謂的頂層路徑,就拿以上結構來講,最外層的文件夾名字是mother_dir它下面的一級路徑就是頂層路徑,也就是說咱們把以上的項目結構改爲以下的樣子:
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---__init__.py ---index.py
咱們把index.py文件從from_test_dir包裏面拿出來放到了monther_dir包裏面,做爲它的子文件,此時,咱們的模塊引入就不會在pycharm中有飄紅提示了。
或者寫成這樣也能夠:
from from_test.tool.xxx import func
func()
也不會飄紅提示。
2,相對導入方法處理這裏之因此會寫這篇博客是由於我要把我寫的腳本放到一個文件夾下面,便於管理,可是在這個過程當中,有一些公共方法,我須要在腳本中互相引入,這些方法也跟腳本在同一個母文件路徑下,此時的引入就出現問題。結構以下示例:
---mother_dir ---from_test_dir ---tools_dir ---__init__.py ---demo.py ---__init__.py ---index.py ---to_test_dir ---__init__.py ---test.py ---__init__.py
仍是把index做爲入口文件,咱們要從index.py中導入to_test_dir這個包裏面的test.py文件中的內容。在index中的代碼以下寫:
from ..to_test.lala import test_func
test_func()
報錯信息以下:
ValueError: attempted relative import beyond top-level package
這裏糾錯,用絕對路徑導入,把相對路徑改爲絕對路徑。
from to_test.lala import test_func test_func()
便可運行pycharm。
可是在命令行運行的時候,會拋錯:
ModuleNotFoundError: No module named 'to_test'
當咱們的ide和命令行的運行結構有歧義的時候,必定要解決命令行的問題,這也就是爲何不少大佬不用ide,只用vim編程的緣由,快,尚未這麼多衍生的問題。
我寫這篇博客核心要解決的就是這個問題
import os import sys DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(DIR)
from to_test.lala import test_func
test_func()
把上面這段粘回去就能用了。命令行運行正常。
你想知道爲何嗎?
我也不知道,本身去看源碼吧,或者嘗試print一些中間結果看看