一、sys.path
我們首先了解下PATH、PYTHONPATH 和 sys.path 的區別
PATH
在PATH中的 python module 不能被 import,在 PATH 中的一些命令,例如 *.exe,可以直接在cmd中運行,而不用明確的路徑,我們在給 python 安裝一些 packages 的時候,有一些 Scripts 被安裝到 /Scripts 文件夾中,如果 /Scripts 文件夾路徑不在 PATH 中,會有提示
PYTHONPATH
如果我們使用 PYTHONPATH 中的 modules,那麼在運行 python 前,就要把 path 加到 os.environ['PYTHONPATH'],在運行 python 後再加,那些模塊不能直接被導入
sys.path
官方文檔說明:A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH
, plus an installation-dependent default.
sys.path 初始化的時候有兩部分:os.environ['PYTHONPATH'] 和 默認的安裝依賴的一些路徑(例如 python 安裝的根目錄 和 pythonxx.zip),是python的搜索模塊的路徑集,是一個list,如下:
sys.path 的作用:
- 與 PYTHONPATH 不同,sys.path 可以在 python 運行後添加我們的 module path,然後直接 import,應該說python只搜索 sys.path 中的 modules,不搜索
- 我們可以通過 os.environ['PYTHONPATH'] 來傳遞我們的 module path(下文會介紹)
3.在實際開發中,默認包含了當前目錄爲搜索路徑,所以,當前目錄下的模塊和子模塊均可以正常訪問。但是若一個模塊需要import平級的不同目錄的模塊,或者上級目錄裏面的模塊,就可以通過修改path來實現
這是即時生效的方法,就是在模塊裏面修改sys.path值,這種方法修改的sys.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
4. 如果是在使用pycharm IDE,可以直接添加需要導入的目錄爲頂層目錄,也就是添加到系統變量
二、os.path
abspath: 返回一個文件的絕對路徑
import os
os.path.abspath("/etc/sysconfig/selinux")
# '/etc/sysconfig/selinux'
os.getcwd()
# '/root'
os.path.abspath("python_modu")
# '/root/python_modu'
os.path.abspath(__file__) # 返回當前文件的絕對路徑
# /opt/project/test3.py
basename: 返回一個目錄的基名
os.path.basename("/etc/sysconfig/selinux")
# 'selinux'
os.path.basename("/usr/local/python3/bin/python3")
# 'python3'
dirname:返回一個目錄的目錄名
os.path.dirname("/etc/sysconfig/selinux")
# '/etc/sysconfig'
os.path.dirname("/usr/local/python3/bin/python3")
# '/usr/local/python3/bin'
還有其他參數可參考:https://www.cnblogs.com/onemorepoint/p/9132976.html、Python os.path() 模塊
說一下日常使用:
os.path.dirname(__file__)返回腳本的路徑
1、必須是實際存在的.py文件,如果在命令行執行,則會引發異常NameError: name '__file__' is not defined
2、在運行的時候如果輸入完整的執行的路徑,則返回.py文件的全路徑如:
python c:/test/test.py 則返回路徑 c:/test ,如果是python test.py 則返回空
3、結合os.path.abspath用,效果會好,如果大家看過一些python架構的代碼的話,會發現經常有這樣的組合
os.path.dirname(os.path.abspath(__file__)),os.path.abspath(__file__)返回的是.py文件的絕對路徑
這就是os.path.dirname(__file__)的用法,其主要總結起來有:
1、不要已命令行的形式來進行os.path.dirname(__file__)這種形式來使用這個函數
2、結合os.path.abspath()使用
可以os.path.abspath()和os.path.dirname()結合使用達到獲取其他路徑的文件名
一個典型的例子就是Python Django獲取.env時
如下圖
DIRNAME = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 讀取數據庫配置文件
config_file = os.path.join(DIRNAME, '.env')
os.environ
官方文檔的意思,根據一個字符串可以映射到一個對象,比如,environ['HOME']是這個平臺的主目錄,作用相當於getenv("HOME")
首次導入os模塊時(通常是在Python啓動期間作爲處理site.py的一部分)捕獲了此映射。 此時間之後對環境所做的更改不會反映在os.environ中,除非直接修改os.environ進行更改。
簡單的說就是可以根據一個字符串映射到系統環境的一個對象,在首次導入os模塊的時候已經捕獲了系統的映射,可以通過os.environ進行更改。
import os
print(os.environ)
比如我們想找一個USER_SETTING,其中並不包含USER_SETTING。
現在我們需要把USER_SETTING添加到系統變量中去。
import os
os.environ['USER_SETTING'] = 'test3'
print(os.environ)