Python中的-m参数
问题
python -m filename.py
作用是把filename.py文件当做模块启动
那么,什么是模块启动?python filename.py
和python -m filename.py
又有什么区别?
python filename.py和python -m filename.py的区别
这是两种加载python文件的方式:
- python filename.py
直接运行 - python -m filename.py
把模块当作脚本来启动
注意:但是__name__的值为’main’
不同的python文件加载方式,主要影响sys.path
这个属性。sys.path
就相当于liunx中的PATH
。
下面来看一下sys.path
(python3Spider) C:\Users\admin>python
Python 3.6.10 |Anaconda, Inc.| (default, Jan 7 2020, 15:18:16) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', 'D:\\Anaconda3\\envs\\python3Spider\\python36.zip',
'D:\\Anaconda3\\envs\\python3Spider\\DLLs',
'D:\\Anaconda3\\envs\\python3Spider\\lib',
'D:\\Anaconda3\\envs\\python3Spider',
'D:\\Anaconda3\\envs\\python3Spider\\lib\\site-packages']
这就是当前python解释器运行的环境,python解释器会在这些目录下去寻找依赖的库。其中,''
为当前目录。
下面有两个例子,通过不同方式启动同一文件run.py
,sys.path
属性的值有何不同。
# run.py 内容如下
import sys
print(sys.path)
# 直接启动:python run.py
(python3Spider) C:\Users\admin\Documents\Python Scripts>python run.py
['C:\\Users\\admin\\Documents\\Python Scripts',
'D:\\Anaconda3\\envs\\python3Spider\\python36.zip',
'D:\\Anaconda3\\envs\\python3Spider\\DLLs',
'D:\\Anaconda3\\envs\\python3Spider\\lib',
'D:\\Anaconda3\\envs\\python3Spider',
'D:\\Anaconda3\\envs\\python3Spider\\lib\\site-packages']
# 模块方式启动:python -m run.py
(python3Spider) C:\Users\admin\Documents\Python Scripts>python -m run.py
['',
'D:\\Anaconda3\\envs\\python3Spider\\python36.zip',
'D:\\Anaconda3\\envs\\python3Spider\\DLLs',
'D:\\Anaconda3\\envs\\python3Spider\\lib',
'D:\\Anaconda3\\envs\\python3Spider',
'D:\\Anaconda3\\envs\\python3Spider\\lib\\site-packages']
区别就是在第一行。
- 直接启动是把
run.py文件
所在的目录放到了sys.path属性中。 - 模块启动是把输入命令的目录(也就是当前路径),放到了sys.path属性中
用途
在开发过程中
# 目录结构如下
package/
__init__.py
mod1.py
package2/
__init__.py
run.py
# run.py 内容如下
import sys
from package import mod1
print(sys.path)
如何才能启动run.py文件?
# 直接启动(失败)
(python3Spider) C:\Users\admin\Documents\Python Scripts>python ./package2/run.py
Traceback (most recent call last):
File "./package2/run.py", line 3, in <module>
from package import mod1
ModuleNotFoundError: No module named 'package'
# 以模块方式启动(成功)
(python3Spider) C:\Users\admin\Documents\Python Scripts>python -m package2.run
['',
'D:\\Anaconda3\\envs\\python3Spider\\python36.zip',
'D:\\Anaconda3\\envs\\python3Spider\\DLLs', 'D:\\Anaconda3\\envs\\python3Spider\\lib',
'D:\\Anaconda3\\envs\\python3Spider',
'D:\\Anaconda3\\envs\\python3Spider\\lib\\site-packages']
当需要启动的python文件引用了一个模块,需要使得sys.path
中包含import的模块的路径。
选择启动方式目的就是把import的那个模块的路径放到sys.path中。
分析
导入一个叫 mod1 的模块时,解释器先在当前目录中搜索名为 mod1.py 的文件。如果没有找到的话,接着会到 sys.path 变量中给出的目录列表中查找。
sys.path
变量的初始值来自如下:
- 输入脚本的目录(当前目录)。
- 环境变量 PYTHONPATH 表示的目录列表中搜索(这和 shell 变量 PATH 具有一样的语法,即一系列目录名的列表)。
- Python 默认安装路径中搜索。
实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录), PYTHONPATH 和安装目录。这样就允许 Python程序了解如何修改或替换模块搜索目录。