python -m引发的对模块的认识
python -m <pythonfile>: 以模块的方式运行
在文件内部,我们一般通过下面的代码来区分当前脚本,是作为模块导入,还是作为脚本直接运行。
if __name__ == '__main__':
print('模块直接运行'); 当文件作为脚本直接运行时,这段代码会产生副作用,输出字符串“模块直接运行”;
当文件作为模块被导入时,不会产生副作用,不输出字符串“模块直接运行”;
回到正题,当我们知道一个模块的名字,但不知道它的路径时,我们可以通过 -m 参数,在 shell 中将该模块当作脚本运行,例如:
python -m module_name 事实上,如果我们知道模块的完整路径(此处假设为"/path/to/module.py"),上述命令的效果,以下面的命令等同
python /path/to/module.py 作者:ccw1078
链接:https://www.jianshu.com/p/323fc9a1d7d2
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
有无 -m 参数的比较
1. python script.py # 直接执行脚本
2. python -m script.py # 当做模块的方式执行,相当于 import 一般情况下,我们会想当然的认为,有无参数 -m 对程序会有不同的影响,但是很可惜,第二种写法是会在程序执行之后报错的。其正确的写法是:丢掉 .py 后缀。
首先直观的观察执行结果,Python 的版本是 3.6.3。
编写 script.py 脚本,内容如下:
import sys
print(sys.path)
print(sys.modules) 直接执行脚本
$ python script.py
['/home/ossifrage/workspaces/python-m', '/usr/lib/python36.zip', '/usr/lib/python3.6', ...]
{..., '__main__': <module '__main__' from 'script.py'>, ...} 当做模块方式执行
$ python -m script
['', '/usr/lib/python36.zip', '/usr/lib/python3.6', ...]
{..., '__main__': <module 'run' from '/home/ossifrage/workspaces/python-m/script.py'>, ...,
'runpy': <module 'runpy' from '/usr/lib/python3.6/runpy.py'>, 'pkgutil': <module 'pkgutil' from '/usr/lib/python3.6/pkgutil.py'>} 显示的内容还有很多,只突出显示出了不同的地方。
通过比较不同的地方,我们发现:
第一种方法——直接运行脚本,当前脚本所在的路径会加入到 sys.path 列表中,但是 sys.modules 字典中的 __main__ 的路径不是绝对路径,只是脚本名称。
第二种方法——当做模块方式运行,当前脚本所在的路径不会加入到 sys.path 列表中,但是 sys.modules 字典中的 __main__ 的路径是绝对路径,同时,还引入了
runpy 和 pkgutil 两个模块。
runpy 的用途:定位并执行该模块。主要用途在于实现命令行 -m 执行 python 模块的效果。
pkgutil 的用途:获取包里面的所有模块列表。pkgutil.get_data() 可读取包内任何文件内容。
模块的导入机制
其实,上面的内容涉及到了 Python 包模块的导入机制。
要理解模块的导入机制,得理解几个关键的名词。sys.path -> sys.modules -> < module >.__dict__。
sys.path:是一个列表。保存着模块的搜索路径。如果路径没有存在与该列表中,可使用 sys.path.append() 导入。
sys.modules: 是一个字典。所有加载到内存中的模块都存放在该字典中。当 import 一个模块的时候,首先会在这个字典中查找是否已经加载了目标模块。
如果已加载,则将模块的名字加入到正在调用 import 的模块的 Local 命名空间(也就是< module >.__dict__)中。如果没有,则从 sys.path 查找,找到后载入内存,
并加入到 sys.modules 字典,名称也将导入到当前模块的 Local 命名空间。 作者:藕丝空间
链接:https://www.jianshu.com/p/934db39a9b6d
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
另外有关模块导入的知识:
https://www.cnblogs.com/Stephen-Qin/p/10391122.html
python -m引发的对模块的认识的更多相关文章
- Python标准库之Sys模块使用详解
sys 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分. 处理命令行参数 在解释器启动后, argv 列表包含了传递给脚本的所有参数, 列表的第一个元素为脚本自身的名称. 使用sy ...
- 基于python的opcode优化和模块按需加载机制研究(学习与个人思路)(原创)
基于python的opcode优化和模块按需加载机制研究(学习与思考) 姓名:XXX 学校信息:XXX 主用编程语言:python3.5 个人技术博客:http://www.cnblogs.com/M ...
- Python之进程 2 - multiprocessing模块
我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序也是一个进程,那么我们也可以在程序中再创建进程.多个进程可以实现并发效果,也就是说, ...
- 【转】Python之正则表达式(re模块)
[转]Python之正则表达式(re模块) 本节内容 re模块介绍 使用re模块的步骤 re模块简单应用示例 关于匹配对象的说明 说说正则表达式字符串前的r前缀 re模块综合应用实例 参考文档 提示: ...
- Python开发之日志记录模块:logging
1 引言 最近在开发一个应用软件,为方便调试和后期维护,在代码中添加了日志,用的是Python内置的logging模块,看了许多博主的博文,颇有所得.不得不说,有许多博主大牛总结得确实很好.似乎我再写 ...
- (转)python标准库中socket模块详解
python标准库中socket模块详解 socket模块简介 原文:http://www.lybbn.cn/data/datas.php?yw=71 网络上的两个程序通过一个双向的通信连接实现数据的 ...
- Python之日志处理 logging模块
Python之日志处理(logging模块) 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logging模块日志流处理流程 使用logging四 ...
- Python中的一些常用模块1
OS模块,sys模块,time模块,random模块,序列化模块 os模块是与操作系统交互的一个接口 OS模块简单的来说是一个Python的系统编程操作模块,可以处理文件和目录这些我们日常手动需要做的 ...
- Python全栈开发【模块】
Python全栈开发[模块] 本节内容: 模块介绍 time random os sys json & picle shelve XML hashlib ConfigParser loggin ...
随机推荐
- Python脚本轻松实现批量图片重命名
************************************************************************** 摘要:网上爬取的图片名字很混乱,格式也比较多,需要 ...
- 序列化之 TLV
目录 序列化之 TLV 1. 紧凑模式 2. 可扩展性 3. 更好的可扩展性 4. 自解释性 5. 跨语言特性 6. 代码自动化:IDL语言 7. 总结 序列化之 TLV 通信协议可以理解两个节点之间 ...
- linux更新grub内核启动参数的方法
#!/bin/bash set -x set -e export PS4=+{$LINENO:${FUNCNAME[0]}} trap 'echo "---NEWKERNARGS=$NEWK ...
- Oracle中NEXTVAL 和 CURRVAL的使用
能够通过在 SQL 语句中使用 NEXTVAL 或 CURRVAL 运算符来訪问序列的值.必须用以 sequence.NEXTVAL 或sequence.CURRVAL 格式驻留在同一个数据库中的序列 ...
- 前端跨域实现的几种方式?及使用Nginx反向代理配置。
早期为了防止CSRF(跨域请求伪造)的攻击,浏览器引入了同源策略(SOP)来提高安全性.而所谓"同源策略",即同域名(domain或ip).同端口.同协议的才能互相获取资源,而不能 ...
- Asp.net Core + Log4net + ELK 搭建日志中心
原文:Asp.net Core + Log4net + ELK 搭建日志中心 Docker中一键安装ELK 对于这种工具类的东西,第一步就直接到docker的hub中查找了,很幸运,不仅有Elasti ...
- 响应断言和json asstion
1.要勾选Additionallly assert value才可以输入下面的预期结果哦
- Linux 进程间通信 共享内存
1.特点: 1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝.如管道当在内核空间创建以后,用户空间需要内存 拷贝,需要拷贝数据,所以效率低. 2)为了在多个进 ...
- java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoa
最近运行ssm项目遇到tomcat启动报错: 解决办法,右击项目选择properties 在Deployment Assembly add 选择maven dedependencies 项目成功运行 ...
- leetcode-126-单词接龙
题目描述: class Solution: def findLadders(self, beginWord: str, endWord: str, wordList: list) -> list ...