import問題:https://zhuanlan.zhihu.com/p/69099185
一、sys模塊
sys模塊是python自帶模塊,包含了與Python解釋器和它的環境有關的函數。利用 import 語句輸入sys 模塊。
dir(sys):通過dir()方法查看模塊中可用的方
1. sys.path
sys.path:包含了Python解釋器自動查找所需模塊的路徑的列表。
在Python啟動時,sys.path根據內建規則和PYTHONPATH變量進行初始化。可以進行append、insert、pop、remove等各種列表相關的操作,但通常都進行append操作,在PYTHONPATH環境變量中增加相應的路徑。sys.path.append("自定義模塊路徑"),這種方法是運行時修改,腳本運行后就會失效的。
sys.path列表里的路徑分為三種:
- 當前執行腳本(主動執行,而不是被其他模塊調用)所在路徑。是列表中的第一個元素,若沒有執行腳本,則是個空字符串。
- 第二種是python內置的標准庫路徑,PYTHONPATH。
- 其他的是安裝的第三方模塊路徑。
python import某個A模塊時,首先會從python的內置模塊中查找,是否含有該模塊的定義。若未查詢到,然后會從sys.path對應的模塊路徑查詢,是否含有對應模塊的定義,如果搜索完成依然沒有對應A模塊時,則拋出import的異常。
2. sys.argv
sys.argv獲取命令行參數, 返回值是List,列表的第一個元素是腳本名稱,第二個元素開始才是真正的參數。文件test.py,內容如下:
import sys
print(sys.argv)
在命令行中運行:python3 test.py 33,輸出如下:
['test.py', '33']
二、導入自定義包:
在實際開發中,默認包含了當前目錄為搜索路徑,所以,當前目錄下的模塊和子模塊均可以正常訪問。一個模塊只會被導入一次,不管你執行了多少次import。這樣可以防止導入模塊被一遍又一遍地執行。
但是若一個模塊需要import平級的不同目錄的模塊,或者上級目錄里面的模塊,就可以通過修改path來實現,方法有以下幾種:
1. 臨時添加模塊完整路徑
使用sys.path.append(path)添加相關的路徑,通過該方法添加的目錄,只能在執行當前文件的窗口中有效,窗口關閉后即失效。個人比較推薦這種方法,比較干凈,避免一些沖突問題。
比如現在的代碼目錄結構:
/src/configs/config.py
/src/common/Database.py
假如Database.py期望導入config.py,則可以增加上級目錄到sys.path列表里面:
parent_path = os.path.dirname(sys.path[0]) 去掉文件名,返回目錄
if parent_path not in sys.path:
sys.path.append(parent_path)
import configs.config
最好加個判斷,避免重復加入。也可以使用下面的代碼:
import sys
sys.path.append(‘../’) # 動態添加a_package文件夾的所在路徑
2. 將模塊保存到指定位置
對 Python 本身進行擴展的模塊,應該直接安裝在 Python 內部以便被所有程序共享,此時就可借助於 Python 默認的模塊加載路徑(保存在 sys.path 變量中)。
通常來說,默認將 Python 的擴展模塊添加在lib\site-packages路徑下,它專門用於存放Python的擴展模塊和包。
3. 設置環境變量
使用PYTHONPATH環境變量,在這個環境變量中輸入相關的路徑,不同的路徑之間用逗號(英文的!)分開。
如果PYTHONPATH 變量不存在,可以創建它!路徑會自動加入到sys.path中,而且可以在不同的python版本中共享,應該是一樣較為方便的方法。
4. 增加.pth文件,推薦!
在site-packages下新建.pth文件(用於添加額外的sys.path),將模塊的絕對路徑寫進去,一行一個路徑。解釋器啟動時,.pth文件里列舉出來的存在於文件系統的目錄將被添加到sys.path。如果它被添加到系統級的Python解釋器,安裝一個.pth文件可能需要管理員權限。
這個不失為一個好的方法,但存在管理上的問題,而且不能在不同的python版本中共享。
三、絕對路徑和相對路徑導包的區別:
1. 絕對路徑導包:
從當前執行腳本所在路徑中導入需要的module。
2. 相對路徑導包:
單點表示引用的模塊或包,與當前模塊在同一目錄中(同一個包中)。
兩點表示引用的模塊,在當前模塊所在位置的父目錄中。
相對導入只適用於頂級包之內的模塊,用了相對導入的模塊文件不能作為頂層執行文件。