python3 使用相對路徑 import模塊

目錄結構

.
├── apt_root.py
├── __init__.py
├── mod/
    └── test.py
    └── __init__.py
└── sub/
    └── test.py
    └── __init__.py

任務一:在mod/test.py中import 上級目錄下的apt_root.py

任務二:在mod/test.py中import 上級目錄的sub/test.py

 

前提

【爲什麼題目限定python3的import?】

因爲網上能搜到的PEP都是python2的。例如PEP328。但是據我觀察,python2和python3的import規則不同。

【絕對路徑他不香嗎,爲什麼限定用相對路徑import模塊?】

通過絕對路徑引用模塊,容易造成在後續改變代碼結構,或者文件改名時,修改工作多的問題。而相對路徑沒有這個問題

 

解析

寫這篇文章的一個出發點,是我發現import並沒有很簡單,至少對我造成了很多混亂,因此在這裏進行分享,希望能上面兩個任務能覆蓋所有困難情況。首先一個混亂,是用不同方式執行test.py,其中的import能不能找到對應module是不同的。

用python test.py的方式

這時,在根目錄下執行python mod/test.py ,

或者 進入mod子目錄再執行python test.py的效果是一樣的。

用網上查到的這些方式都會報錯:

from . import apt_root
# 或者
from .. import apt_root
# 或者
from ..apt_root import *

我測試成功的寫法是這樣:

import sys

sys.path.append(".")
import app_root

所以,應該一個‘.’是上一級目錄,兩個'.'是上兩級。意思是把上一級目錄加入搜索路徑。

用python -m test的方式

這種方式下,如果我的import是這樣:

import app_root

(和直接python xxx.py不同)在不同目錄下運行,會有不同效果!

一:在根目錄下:python -m mod.test——運行成功

二:先進入mod子目錄,再python -m test——運行失敗

如果要運行成功,則應該這樣:

sys.path.append("..")
import app_root

(又一個造成混亂的)python -m xxx時,把上級目錄加入搜索路徑,要用"..",這和python xxx.py時,用"."代表上級目錄不同!

原因是python -m方式,會把當前運行命令的路徑添加至sys.path。參見[python]自問自答:python -m參數?

所以,這種方法下,一定要結合當前運行命令的路徑+默認sys.path中搜索路徑+代碼中sys.path.append新增路徑,才能判斷import是否能成功。

 

總結

容易造成混亂的地方:

1.相對路徑的使用不能用from .. import XX,而要用sys.path.append(“..”)

2.python -m xxx和python xxx.py對import的寫法中上級目錄表示不同,前者用兩個點,後者用一個點;

3.python -m xxx中import搜索路徑與當前執行命令的目錄相關;

python xxx.py與當前執行命令的目錄無關

 

 


【歡迎關注我的微信公衆號:人工智能Beta】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章