python -m參數

查看 Python 的 help 內容

$ python --help
...
-m mod : run library module as a script (terminates option list)
# 直譯就是按照腳本的方式執行模塊
...

有無 -m 參數的比較

1. python script.py # 直接執行腳本
2. python -m script.py # 當做模塊的方式執行,相當於 import

一般情況下,我們會想當然的認爲,有無參數 -m 對程序會有不同的影響,但是很可惜,第二種寫法是會在程序執行之後報錯的。其正確的寫法是:丟掉 .py 後綴。

首先直觀的觀察執行結果,Python 的版本是 3.6.3。
編寫 script.py 腳本,內容如下:

import sys
print(sys.path)
print(sys.modules)
直接執行腳本

$ python script.py
['/home/ossifrage/workspaces/python-m', '/usr/lib/python36.zip', '/usr/lib/python3.6', ...]
{..., '__main__': <module '__main__' from 'script.py'>, ...}

當做模塊方式執行

$ python -m script
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', ...]
{..., '__main__': <module 'run' from '/home/ossifrage/workspaces/python-m/script.py'>, ..., 'runpy': <module 'runpy' from '/usr/lib/python3.6/runpy.py'>, 'pkgutil': <module 'pkgutil' from '/usr/lib/python3.6/pkgutil.py'>}

顯示的內容還有很多,只突出顯示出了不同的地方。

通過比較不同的地方,我們發現:

第一種方法——直接運行腳本,當前腳本所在的路徑會加入到 sys.path 列表中,但是 sys.modules 字典中的 __main__ 的路徑不是絕對路徑,只是腳本名稱。

第二種方法——當做模塊方式運行,當前腳本所在的路徑不會加入到 sys.path 列表中,但是 sys.modules 字典中的 __main__ 的路徑是絕對路徑,同時,還引入了 runpypkgutil 兩個模塊。

runpy 的用途:定位並執行該模塊。主要用途在於實現命令行 -m 執行 python 模塊的效果。

pkgutil 的用途:獲取包裏面的所有模塊列表。pkgutil.get_data() 可讀取包內任何文件內容。

模塊的導入機制

其實,上面的內容涉及到了 Python 包模塊的導入機制。

要理解模塊的導入機制,得理解幾個關鍵的名詞。sys.path -> sys.modules -> < module >.__dict__。

sys.path:是一個列表。保存着模塊的搜索路徑。如果路徑沒有存在與該列表中,可使用 sys.path.append() 導入。

sys.modules: 是一個字典。所有加載到內存中的模塊都存放在該字典中。當 import 一個模塊的時候,首先會在這個字典中查找是否已經加載了目標模塊。如果已加載,則將模塊的名字加入到正在調用 import 的模塊的 Local 命名空間(也就是< module >.__dict__)中。如果沒有,則從 sys.path 查找,找到後載入內存,並加入到 sys.modules 字典,名稱也將導入到當前模塊的 Local 命名空間。

轉自segmentfault-藕絲空間

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