python -m详解
Python微信订餐小程序课程视频
https://edu.csdn.net/course/detail/36074
Python实战量化交易理财系统
https://edu.csdn.net/course/detail/35475
温馨提示: 本篇演示环境是
Python 3.8
先python --help
看下python -m
参数的解释:
-m mod : run library module as a script (terminates option list)
mod
是module
的缩写,即-m
后面跟的是模块(module
)名,意思是把模块当成脚本来运行。
terminates option list
意味着-m
之后的其它选项不起作用,在这点上它跟-c
是类似,都是终极选项。
既然涉及到模块,这里就多提几句。 在Python中,一个.py
文件就称之为一个模块(Module
)。
比如一个顶层包名bytesfly
,按照如下目录存放:
bytesfly
├─ __init__.py
├─ __main__.py
└─ fly.py
上面fly.py
模块的名字就是bytesfly.fly
。
注意: 模块名是不带.py
后缀的。
关于模块更详细的讲解见之前的博客:
https://blog.csdn.net/bytesfly/p/python.html#模块
python -m 常见用法
- 使用
cProfile
模块分析程序函数调用链耗时
python -m cProfile -s cumulative bytesfly/fly.py
- 使用
pdb
模块以调试模式来执行Python脚本
python -m pdb bytesfly/fly.py
- 使用
http.server
模块实现一个简单的HTTP服务
python -m http.server 9000
- 使用
pydoc
模块生成HTML格式的官方帮助文档,可以在浏览器中访问
python -m pydoc -p 9001
- python -m pip install xxx
在存在多个Python版本的环境中,这种写法可以精确地控制三方库的安装位置。例如用python3.8 -m pip
,可以明确指定给3.8
版本安装,而不会混淆成其它的版本。
当然现在我们大多使用conda
之类的虚拟环境管理器和包管理器,可能不会出现上面所说的这种混淆情况。这里只是提一下。
- 使用
timeit
模块分析执行耗时
python -m timeit -n 3 -r 2 "import time;time.sleep(1)"
其实调用的是:
timeit.repeat("import time;time.sleep(1)", repeat=2, number=3)
看一眼timeit.py
中的源码就能快速理解-n
-r
参数的意思:
def repeat(self, repeat=default\_repeat, number=default\_number):"""Call timeit() a few times.This is a convenience function that calls the timeit()repeatedly, returning a list of results. The first argumentspecifies how many times to call timeit(), defaulting to 5;the second argument specifies the timer argument, defaultingto one million."""r = []for i in range(repeat):t = self.timeit(number)r.append(t)return r
-p/–process: use time.process_time() (default is time.perf_counter())
timeit
后面还能添加-p
参数,如下:
python -m timeit -p -n 3 -r 2 "import time;time.sleep(1)"
其实调用的是:
timeit.repeat("import time;time.sleep(1)", repeat=2, number=3, timer=time.process_time)
再看一眼time.process_time()
的代码注释
def process\_time(): # real signature unknown; restored from \_\_doc\_\_"""process\_time() -> floatProcess time for profiling: sum of the kernel and user-space CPU time."""return 0.0
加上了-p
参数计算的是sum of the kernel and user-space CPU time
,讲白了就是程序占用CPU的时间,程序睡眠或者请求网络IO阻塞的时间不算。
python -m 原理解析
看了上面python -m
几种常见用法,你是否好奇python -m
到底做了什么事?
不卖关子,一句话解释就是:
对于
python -m module_name
,Python会检索sys.path
,查找名字为module_name
的模块或者包,并将其内容当成主程序入口来执行,换句话说在执行时,该脚本的__name__
是__main__
。
拿文章开篇的bytesfly.fly
模块来说,也就是bytesfly
包下的fly.py
文件内容如下:
import sysprint("----fly----")if __name__ == '\_\_main\_\_':print("fly\_main")print(sys.path)
在hello
项目路径下执行python -m bytesfly.fly
,输出如下:
----fly----
fly_main
['/home/bytesfly/py/hello', '/home/bytesfly/anaconda3/envs/test/lib/python38.zip']
如果直接执行呢? 即相同路径下执行python bytesfly/fly.py
,输出如下:
----fly----
fly_main
['/home/bytesfly/py/hello/bytesfly', '/home/bytesfly/anaconda3/envs/test/lib/python38.zip']
总结一下,python -m module_name
与python folder/file.py
,都会把定位到的Python脚本当成主程序入口来执行,即在执行时,该脚本的__name__
都是__main__
,与import
导入模块不同。
但是有注意到上面两种调用方式的不同之处吗?
fly.py
程序输出了sys.path
,可以看到两种调用方式的Python Path
有区别,这种区别有什么影响呢?
再看一个例子。 比如一个顶层包名还是bytesfly
,按照如下目录存放:
bytesfly
├─ __init__.py
├─ __main__.py
└─ fly.py
└─ a├─ __init__.py└─ run.py
└─ b├─ __init__.py└─ tool.py
其中tool.py
内容如下:
def add(a, b):return a + b
其中run.py
内容如下:
import sysprint(sys.path)if __name__ == '\_\_main\_\_':from bytesfly.b import toolprint(tool.add(1, 2))
同样在hello
项目路径下执行python -m bytesfly.a.run
,输出如下:
['/home/bytesfly/py/hello', '/home/bytesfly/anaconda3/envs/test/lib/python38.zip']
3
然后在hello
项目路径下执行python bytesfly/a/run.py
,输出如下:
['/home/bytesfly/py/hello/bytesfly/a', '/home/bytesfly/anaconda3/envs/test/lib/python38.zip']
Traceback (most recent call last):File "bytesfly/a/run.py", line 6, in from bytesfly.b import tool
ModuleNotFoundError: No module named 'bytesfly'
这个地方能Get到这两种调用方式在Python Path
上的区别?
除此之外,python -m module_name
与python folder/file.py
,在实现上有什么不同呢?
- 使用
python -m module_name
,解释器在不import
模块的情况下,在所有模块命名空间中查找,定位到脚本的路径,然后执行。为了实现这个过程,解释器会借助两个模块:pkgutil
和runpy
,前者用于获取所有的模块列表,后者根据模块名来定位并执行脚本 - 直接运行脚本时,相当于给出了脚本的完整路径(不管是绝对路径还是相对路径),解释器根据文件系统的查找机制,定位到该脚本,然后执行
python -m 补充说明
python -m module_name
这里的module_name
也可以是包名。
还是用上面的顶层包名bytesfly
举例,按照如下目录存放:
bytesfly
├─ __init__.py
├─ __main__.py
└─ fly.py
└─ a├─ __init__.py└─ run.py
└─ b├─ __init__.py└─ tool.py
其中__main__.py
内容如下:
import sysprint("---bytesfly---")if __name__ == '\_\_main\_\_':print(sys.path)
项目路径下执行python -m bytesfly
,输出如下:
---bytesfly---
['/home/bytesfly/py/hello', '/home/bytesfly/anaconda3/envs/test/lib/python38.zip']
如果执行python -m bytesfly.a
,输出如下:
No module named bytesfly.a.__main__; 'bytesfly.a' is a package and cannot be directly executed
原来,python -m bytesfly
等效于python -m bytesfly.__main__
。
写在最后
有了python -m module_name
选项,在命令行中使用内置模块、标准包与第三方模块更加方便。
参考:
https://blog.csdn.net/pythonista/p/11829632.html
https://blog.csdn.net/xueweihan/p/5118222.html
python -m详解相关推荐
- python区块链开发_Fabric区块链Python开发详解
Hyperledger Fabric是最流行的联盟区块链平台.Fabric区块链Python开发详解课程 涵盖Fabric区块链的核心概念.Fabric网络搭建.Node链码开发.Python应用开发 ...
- python装饰器setter_第7.27节 Python案例详解: @property装饰器定义属性访问方法getter、setter、deleter...
上节详细介绍了利用@property装饰器定义属性的语法,本节通过具体案例来进一步说明. 一. 案例说明 本节的案例是定义Rectangle(长方形)类,为了说明问题,除构造函数外,其他方法都只 ...
- 【python】详解类class的继承、__init__初始化、super方法
原文链接; https://blog.csdn.net/brucewong0516/article/details/79121179?utm_medium=distribute.pc_relevant ...
- python与golang_Golang与python线程详解及简单实例
Golang与python线程详解及简单实例 在GO中,开启15个线程,每个线程把全局变量遍历增加100000次,因此预测结果是 15*100000=1500000. var sum int var ...
- python 最小二乘法_最小二乘法及其python实现详解
最小二乘法Least Square Method,做为分类回归算法的基础,有着悠久的历史(由马里·勒让德于1806年提出).它通过最小化误差的平方和寻找数据的最佳函数匹配.利用最小二乘法可以简便地求得 ...
- 【python】详解multiprocessing多进程-Pool进程池模块(二)
[python]详解multiprocessing多进程-process模块(一) [python]详解multiprocessing多进程-Pool进程池模块(二) [python]详解multip ...
- 【python】什么是序列,Python序列详解
什么是序列,Python序列详解 概述 序列索引 序列切片 序列相加 序列相乘 检查元素是否包含在序列中 序列相关的内置函数 range 快速初始化数字列表 概述 所谓序列,指的是一块可存放多个值的连 ...
- python多线程详解 Python 垃圾回收机制
文章目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 总结起来,使用多线程编程具有如下几个优点: 二.线程实现 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 ...
- Python线程详解
Python线程详解 线程简介 开启多线程 线程之间共享 GIL全局解释器锁 线程间通信 线程简介 线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元. ...
- 07 Python数据类型详解
文章目录 一.整数类型(int)详解 1.1 整数的不同进制 1) 十进制形式 2) 二进制形式 3) 八进制形式 4) 十六进制形式 1.2 数字分隔符 1.3 相关方法 二.字符串类型(strin ...
最新文章
- OpenCV(项目)车牌识别4 -- 总结篇
- 十个效果酷炫的Linux系统操作指令(像黑客帝国般的效果~)
- spark和python的关系_spark submit和pyspark有什么区别?
- Android studio Merge 标签 显示错乱
- 为何python不好找工作k-为什么我不建议你通过 Python 去找工作?
- 论营销的重要性:以一个磁铁为例
- luogu P2572 [SCOI2010]序列操作
- java判断字符串是否为数字或中文或字母
- Flutter设置允许HTTP访问
- 商(quotient)—— 两数之比
- java 多项式拟合最多的项数_MATLAB绘制带置信区间的拟合曲线
- UDS学习笔记(六)——程序刷写
- FPGA代码规则检查工具
- 软件项目管理课程设计-数字化校园学工信息系统
- 杭电1856——并差集
- 自定义控件从入门到轻生之---初尝禁果
- NGINX 0 DAY LDAP RCE 漏洞来龙去脉
- WCDMALTE Linux移远USB驱动程序用户指南(WCDMA/LTE Standard/Automotive/LTE-A Module Series)
- 推荐7个Python自动化办公免费学习资源~(数据分析、Python、VBA等)
- android前端切片,安卓前端快速开发工具-安卓切片_菜单介绍
热门文章
- android之基于百度语音合讯飞语音识别的语音交互
- jlink怎么调试linux程序_【转】ubuntu linux下openocd + gdb-insight 用Jlink调试arm程序
- 地理信息系统名词解释大全(二)
- 网络云存储技术Windows server 2012 (项目十 基于NTFS权限(ADLP原则)的文件共享服务的配置与管理)
- 推荐系统架构与算法流程详解
- 可控制导航下拉方向的jQuery下拉菜单代码
- 【JavaEE】文件
- python2.7安装pytorch_Pytorch如何安装,Linux安装Pytorch,OSX安装Pytorch教程
- MII与RMII接口的区别
- SSH免密登录(笔记)