Python -m 选项的作用
2017-01-24
在运行pip安装软件的时候,有些文档的写法如下
# python -m pip install xxx
看下python的帮助文档
# main python
-m module-name
Searches sys.path for the named module and runs the corresponding .py file as a script.
直译过来就是以脚本的方式运行模块的相应py文件, 但是通过测试发现,大部分模块是不能这么玩的,比如:
# python -m urllib3
/usr/bin/python: No module named urllib3.__main__; 'urllib3' is a package and cannot be directly executed
# python -m yum
/usr/bin/python: No module named yum.__main__; 'yum' is a package and cannot be directly executed
# python -m werkzeug
/usr/bin/python: No module named werkzeug.__main__; 'werkzeug' is a package and cannot be directly executed
# python -m flask
/usr/bin/python: No module named flask.__main__; 'flask' is a package and cannot be directly executed
那为什么pip能用python -m执行? 为此我来实现一个可以用python -m执行的模块
1.先按正常方式定义一个model模块, 里面只有一个do.py文件, 执行具体的函数; test.py为调用这个模块的测试程序
# tree
.
|-- model
| |-- do.py
| `-- __init__.py
`-- test.py
# file: do.py
def echo(v):
print "get:%s" % v
# file: __init__.py
# __init__.py只是一个空文件,告诉python 把model当一个模块来处理
# file: test.py
import sys
from model import do
if __name__ == "__main__":
if len(sys.argv) < 2:
sys.exit(1)
do.echo(sys.argv[1])
执行效果就是直接显示传入的参数
# python test.py xxx
get:xxx
但这个时候,我们使用-m选项还是不能执行的, 我们需要进行第二步
# python -m model xxx
/usr/bin/python: No module named model.__main__; 'model' is a package and cannot be directly executed
2.在model下创建一个__main__.py文件, 发现这个文件的内容和上面的test.py的文件差不多,
# tree
.
`-- model
|-- do.py
|-- __init__.py
`-- __main__.py
# file: __main__.py
import sys
import do
if __name__ == "__main__":
if len(sys.argv) < 2:
sys.exit(1)
do.echo(sys.argv[1])
这个时候,我们再使用-m选项,发现已经可以正常执行了
# python -m model xxx
get:xxx
所以: 其实python -m在执行的时候,会到sys.path下寻找这个模块, 然后在这个模块下执行__main__.py
再来回头看看pip, 它能直接python -m pip执行,是因为pip也有这个__main__.py
文件
# rpm -ql python2-pip | grep __main__.py
/usr/lib/python2.7/site-packages/pip/__main__.py
/usr/lib/python2.7/site-packages/pip/__main__.pyc
/usr/lib/python2.7/site-packages/pip/__main__.pyo
有兴趣的同学可以对比下__main__.py
和/usr/bin/pip
的内容,其实是一样的
# cat /usr/bin/pip
# cat /usr/lib/python2.7/site-packages/pip/__main__.py
问题 : 既然pip install xxx
能用,-m pip install xxx
也能用,为啥需要第二种复杂又难理解的方式呢???