DoubleLi

qq: 517712484 wx: ldbgliet

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  4737 随笔 :: 2 文章 :: 542 评论 :: 1615万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

今天再看python的项目时,发现GitHub中给出的python脚本的执行格式是python -m pip install somepackage。于是开始了python模式启动之旅。

其中很多相关借鉴了该博客,同时感谢博主:http://www.cnblogs.com/xueweihan/p/5118222.html

  • 什么是python启动模块:

通过python启动一个库中的模块(python启动模块):

python -m http.server    (python3中启动一个简单的http服务器)

  • 关于python的模块方式启动

python 的启动方式(加载py文件方式)有两种:

 

  1. python xxx.py  -----直接运行的方式启动(此时脚本__name__为"__main__")
  2. python -m xxx.py  ------以模块的方式启动(此时脚本的__name__属性值依然不再是"__main__"而是"xxx")

附:__name__ == "__main__"表示该脚本为程序的主入口,否则是以模块调用的形式运行。

区别1:

关于两种启动方式的差异,主要是所加载的系统路径不同(sys.path列表):(通过列子做了验证)

在/home/spark/cluster-master/examples下建立test.py脚本,内容:

 
 
import sys
 
print(sys.path)
 
 
 

1、直接运行:python test.py结果:

['/home/spark/cluster-master/examples', '/home/spark/cluster-master', '/data/lthpc/soft/caffe/python', '/opt/anaconda3/lib/python36.zip', '/opt/anaconda3/lib/python3.6', '/opt/anaconda3/lib/python3.6/lib-dynload', '/opt/anaconda3/lib/python3.6/site-packages', '/opt/anaconda3/lib/python3.6/site-packages/Sphinx-1.5.6-py3.6.egg', '/opt/anaconda3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg', '/opt/anaconda3/lib/python3.6/site-packages/torchvision-0.1.9-py3.6.egg']
 
 

2、以模块方式运行 :python -m test结果:

['', '/home/spark/cluster-master/examples', '/data/lthpc/soft/caffe/python', '/opt/anaconda3/lib/python36.zip', '/opt/anaconda3/lib/python3.6', '/opt/anaconda3/lib/python3.6/lib-dynload', '/opt/anaconda3/lib/python3.6/site-packages', '/opt/anaconda3/lib/python3.6/site-packages/Sphinx-1.5.6-py3.6.egg', '/opt/anaconda3/lib/python3.6/site-packages/setuptools-27.2.0-py3.6.egg', '/opt/anaconda3/lib/python3.6/site-packages/torchvision-0.1.9-py3.6.egg']
 
 

注意不同之处来了:直接运行后添加到path中的路径为”脚本所在路径“,而以模块方式运行后多了一个‘ ’,这个‘ ’符号代表python执行运行环境的当前路径(即为python的执行路径),就是这个‘ ’当前路径引出了import包时的很多问题。下面用例子说明:

下面的例子我在服务器上没有验证成功,先姑且贴一下别人的例子:

 
 
# 目录结构如下
 
package/
 
__init__.py
 
mod1.py
 
package2/
 
__init__.py
 
run.py
 
 
 
 
 
# run.py 内容如下
 
import sys
 
from package import mod1
 
print(sys.path)
 
 
 

 

两种启动:

 

 
 
# 直接启动(失败)
 
➜ test_import_project git:(master) ✗ python package2/run.py
 
Traceback (most recent call last):
 
File "package2/run.py", line 2, in <module>
 
from package import mod1
 
ImportError: No module named package
 
 
 
# 以模块方式启动(成功)
 
➜ test_import_project git:(master) ✗ python -m package2.run
 
['',
 
'/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python27.zip',
 
...]
 
 
 

启动成功与否的关键是在run.py脚本中的import 内容能否成功地加入到sys.path中。

显然from package import mod1,在sys.path中存在' '当前路径的情况下是能够找到对应包的,而另一种方式找不到包,原因在于python 的模块搜索路径机制:

区别2:

  • 当加上-m参数时,Python会先将模块或者包导入,然后再执行。

假设我们有如下一个包package

 
 
package
 
├── __init__.py
 
└── __main__.py
 
 
 

__init__.py的内容

 
 
import sys
 
 
 
print("__init__")
 
print(sys.path)
 
 
 

__main__.py的内容

 
 
import sys
 
 
 
print("__main__")
 
print(sys.path)
 
 
 

使用python -m package运行,输出结果:

 
 
__init__
 
['', ...]
 
 
 
__main__
 
['', ...]
 
 
 

使用python package运行,输出结果:

 
 
__main__
 
['package', ...]
 
 
 

这里涉及到__main__为名称的模块,__main__.py文件是一个包或者目录的入口程序。不管是用python package还是用python -m package运行,__main__.py文件总是被执行。 

 

在一个模块被导入时,PVM会在后台从一系列路径中搜索该模块,其搜索过程如下:

1、在当前目录下搜索该模块;

2、在环境变量PYTHONPATH中指定的路径列表中依次搜索;

3、在python安装路径中搜索

      事实上,PVM通过变量sys.path中包含的路径来搜索,这个变量里面包含的路径列表就是上面提到的这些路径信息。

 

posted on   DoubleLi  阅读(90)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2012-12-15 java中的“包”与C#中的“命名空间
2012-12-15 C|C++中的静态全局变量,静态局部变量,全局变量,局部变量的区别
2012-12-15 const int *p和int * const p的区别(常量指针与指向常量的指针) .
点击右上角即可分享
微信分享提示