python -m引數的含義和用法
上一篇文章介紹了python程式碼的計時工具line_profiler,其可以計算每行程式碼的執行時間,十分之好用,但是最後的一小節有說到其在計時的同時還可以生成一個結果檔案,若是有需要的話可以再使用python -m命令檢視其結果。其命令使用方式如下:
python -m line_profiler test.py.lprof
由於個人比較好奇,我就多方查閱資料,但網上各位大佬的部落格寫的可能有點深奧,同時也並未清晰明瞭地展示其能達到功能,我還是花了好久才最終終於大概弄懂了這個-m的含義以及到底它有什麼用。當然這可能也是因為我的理解能力較差,吼吼吼。
今天就簡單解釋一下python -m的含義啦。
文章目錄
python -h中對python -m的解釋
我們平常在命令列中可能大都會使用python + 指令碼名(例如python test.py)來執行指令碼吧,這樣其實就能看出來了python實際上就是一個命令或者說是一個軟體,因此python也具有很多可用的引數,要檢視這些引數可以在命令列使用python -h檢視幫助文件即可。
在這個幫助文件中,可以看到對-m 的解釋是:
-m mod : run library module as a script (terminates option list)
也就是將一個python library 中的模組當做指令碼來執行。這裡實際上可能理解能力強的人就已經能理解了,那你可能看你情況還要不要看下去哈,我是沒有一眼就搞懂的。
python -m 的作用及使用方法
將模組當做指令碼來執行,是因為一般情況下模組是通過import後,我們再使用模組中的各種函式或者功能的。但是正如之前的某篇文章說過的一樣,在python指令碼中一般會有一個如下的語句:
if __name__ == "__main__": # 這裡不知道怎麼打出來,只能在程式碼塊裡打了 main()
這個語句就是防止別人呼叫這個指令碼中會直接執行main的內容,而單獨執行此指令碼時則可以執行main中的內容。
這裡針對模組來說,模組一般是被通過import引入的,例如正則re,畫圖的turtle、還有site模組等。引入模組時只需要輸入指令碼字首即可,不需要輸入字尾.py。在python自帶庫中有很多模組是沒有上面的if 語句的,也就是它們一般不會直接被執行(例如使用python re.py的情況),但某些庫是帶有這種語句的,例如site模組:
也就是在特定情況下我們可以將這個模組當做指令碼來執行。這時候本文介紹的python -m引數就派上用場啦,python -m 表示我們把後面跟的引數當做是一個模組,執行結果也就像執行其它的python指令碼一樣,也會執行main中的內容,只不過這裡就是特定的識別後續跟的是模組(因為是模組,所以直接寫檔案字首即可)。
除上述的點外,python -m由於將後面跟的引數當做模組,因此其會到sys.path也就是python搜尋所需模組的路徑集去尋找對應的模組,這就有點類似系統的環境變數,當引入某個模組時,就會去到sys.path中尋找到這個模組並載入記憶體。sys.path是一個列表,可以自定義地增加路徑。通過上面的介紹,總結一下也就是我們只要知道某個已有模組的模組名(即此模組已經被安裝,例如通過pip安裝的line_profiler),就可以使用python -m + 模組名 的方式執行這個模組指令碼了,不需要輸入模組指令碼所處的絕對位置(前提是模組處於sys.path中哈)。
為了幫大家更好理解,看一下我的sys.path吧(可以放大看哈)!
# 這裡site模組含有if __name__ == '__main__' 語句,其可以通過python -m執行,
# 但我也不知道有什麼用哈,就演示一下
# site模組在我電腦上的絕對路徑為
# C:\Users\MyPC\AppData\Local\Programs\Python\Python38\Lib\site.py
python -m site
# 在命令列執行,結果為:
'''
sys.path = [
'D:\\Backup\\桌面',
'C:\\ProgramData\\Anaconda3\\python38.zip',
'C:\\ProgramData\\Anaconda3\\DLLs',
'C:\\ProgramData\\Anaconda3\\lib',
'C:\\ProgramData\\Anaconda3',
'C:\\Users\\MyPC\\AppData\\Roaming\\Python\\Python38\\site-packages',
'C:\\ProgramData\\Anaconda3\\lib\\site-packages',
'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\win32',
'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\win32\\lib',
'C:\\ProgramData\\Anaconda3\\lib\\site-packages\\Pythonwin',
]
USER_BASE: 'C:\\Users\\MyPC\\AppData\\Roaming\\Python' (exists)
USER_SITE: 'C:\\Users\\MyPC\\AppData\\Roaming\\Python\\Python38\\site-packages' (exists)
ENABLE_USER_SITE: True
'''
sys.path與sys.modules
其實對於除了python sys.path路徑中的各種模組外,平常使用-m的機會可能還是不多,因為正常情況下使用-m和不使用-m的結果是一樣的。
很多博文寫的是通過使用python直接執行指令碼和使用python -m來執行指令碼產生的sys.path,但不知道為啥我執行後兩個的sys.path相同,我就沒有進一步去理解了。讀者可以自己試試哈。
# 假設命名為test.py
import sys
print(sys.path)
print(sys.modules)
# 在命令列使用python -m test和python test.py的產生的sys.path結果相同。
# 產生的sys.modules的結果不同
python執行某指令碼時所有載入到記憶體的模組都放在sys.modules中,使用python執行指令碼和使用python -m兩種方式不同的地方在於
- ‘main’: <module ‘main’ from ‘test.py’ # (普通方式)
- ‘main’: <module ‘test’ from ‘D:\Backup\桌面\test.py’ # (-m方式)
可以看出後者被當做了模組,前者則是指令碼中的main被當做了模組。
可能使用python -m的情況
雖說使用機會少,但是看了網上博主們的部落格後發現還是有可能用上的。舉個例子就行啦:
比如我這裡有一個test.py和一個資料夾123,資料夾中還有一個n.py
# test.py內容
# nothing
# n.py內容
import sys
import test
print(sys.path)
print(sys.modules)
在命令列使用:
python -m 123.n
# 這個命令是可以執行的,也就是123.n被當做了模組,這或許也是python各種庫的
# 組成方式吧,不是很懂,先使用一下吧。在123資料夾中的n.py寫上import test 可能大家覺得不太行,
# 但是實際上是可以的哦,這是因為sys.path在這種方式下是包含了上一級目錄的,也就是包含123這個資料夾
# 和test.py這個檔案的路徑。大家可以多理解一下下!
# 這種使用點號的方式也不是很懂,以後再慢慢學習吧!
這種方式的使用使我們在需要匯入某個指令碼時不用一定要移動指令碼,還是會有一定用處的哈。我覺得平常在自己的指令碼中能使用的可能就是這種情況啦!
叮
實際上我也還有點不是很懂,先寫下這些,哈哈,以後有更深的理解再把內容加上。