长话短说
简单来说,-m
参数的作用有两个:
- 简化运行方式,你可以直接运行在
sys.path
下的模块而不需要指定具体路径(如果直接用python pkgpath
则要指明具体路径) - 它会将当前执行的目录也加入到
sys.path
,这样即使在代码中使用相对或绝对路径import package_path也是可以运行的(否则就只能引用sys.path中的package了)
具体的
模块
python中的模块分两种:
- 一般的python文件,例如
xxx.py
,这个称之为“代码模块” - 一个包含其他模块的目录,这个称之为“包模块”,其目录下的模块既可以是代码模块,也可以是包模块。一般情况下,其目录下会存在一个名为__init__.py的文件
最初-m
参数提出来就是为了简化模块的运行方式,例如对于 SimpleHTTPServer
(python3中是 http.server
),在没有该参数出来之前你需要指定该包的具体路径才能运行
python xxx/xxx/xxx.py
在此之后,因为该包在sys.path
中,你只需要直接运行包名即可(注:包名不包含.py
后缀)
python -m xxx
事实上,这两种方式运行的效果是一样的,使用-m参数后python解释器会自动帮你找到模块的绝对路径,这和直接在代码中 import module 本质上是一样的
如果某目录(模块)下存在“__main__.py”文件,则你可以直接运行该模块,例如你在 “testmodule” 目录下有两个文件

你可以运行
# 均在上述Tmp目录下
python .\testmodule\
# 或
python -m testmodule

注1:如果是以模块方式运行,则其模块下的“__init__.py”会先运行
注2:import module时也会执行module下的“__init__.py”,如果module就是一个py文件时,它会先将该文件执行一遍
sys.path
sys.path是一个目录数组,你在import module时,python解释器就会遍历这些目录去寻找相应的module,如果没找到就报找不到module的错误,当在命令行中使用-m参数运行module时,它会自动将当前目录加入到sys.path中去,否则就不会,可以在代码中打印出来看看
添加
可以直接使用 sys.path.append(dir)
进行添加,这里需要注意的是,如果使用如下代码进行添加则可能会出问题:
# 以下为错误做法:这里实际上指的不是当前文件所在目录,而是你运行py文件时所在的目录
module_dir = os.path.abspath('./')
# 以下为正确做法,要获取文件所在位置,然后再根据该位置进行调整
module_dir = os.path.abspath(os.path.join(os.path.abspath(__file__), ".."))
sys.path.append(module_dir)

if __name__ == “__main__”:
__name__是个魔法属性,当你执行某module时,该module的 __name__就会等于”__main__”,如果是import的module,则该module的__name__就等于该module的名称
import 代码模块时,python解释器会先从头到尾执行一遍该代码模块的代码,有些代码你不想这个时候运行,例如一些测试该模块的代码。此时你就可以将这部分代码放在“if __name__==”main””中,只有你主动执行该模块时,这段代码才会执行
参考
https://stackoverflow.com/questions/7610001/what-is-the-purpose-of-the-m-switch