python -m

长话短说

简单来说,-m 参数的作用有两个:

  1. 简化运行方式,你可以直接运行在sys.path下的模块而不需要指定具体路径(如果直接用python pkgpath则要指明具体路径)
  2. 它会将当前执行的目录也加入到sys.path,这样即使在代码中使用相对或绝对路径import package_path也是可以运行的(否则就只能引用sys.path中的package了)

具体的

模块

python中的模块分两种:

  1. 一般的python文件,例如 xxx.py,这个称之为“代码模块”
  2. 一个包含其他模块的目录,这个称之为“包模块”,其目录下的模块既可以是代码模块,也可以是包模块。一般情况下,其目录下会存在一个名为__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

https://stackoverflow.com/questions/46319694/what-does-it-mean-to-run-library-module-as-a-script-with-the-m-option

Leave a Comment