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:Django 简介。
Django是基Python的重要WEB框架. 1.安装Django Web框架 安装 pip 安装 在命令行模式 执行 [pip install django == 2.0]或者 [pip in ...
- 解析TextView中的URL等指定特殊字符串与点击事件
使用TextView时,有时可能需要给予TextView里的特定字符串,比如URL,数字特别的样式,必希望能够添加点击事件.比如发短信时,文字里的url就可以点击直接打开浏览器,数字可以点击拨打电话. ...
- (Struts2学习系列二)Struts2动态方法调用:指定method属性
紧接着上一篇,在HelloWorldAction.java中添加add和update方法: public class HelloWorldAction extends ActionSupport{ p ...
- kubeadm部署一个Kubernetes集群
kubeadm是官方社区推出的一个用于快速部署kubernetes集群的工具.这个工具能通过两条指令完成一个kubernetes集群的部署: # 创建一个 Master 节点 $ kubeadm in ...
- 自定义Java annotation
1.目录结构: 2.pom文件: Simple exmple: package com.yuan.simple; import java.lang.annotation.Retention; impo ...
- UDP部分
IP地址:互联网协议地址,计算机的通行证.计算机在网络中的唯一身份标识.桥接:Ubuntu虚拟机 直接连到局域网NAT:网络地址转换点分十进制:192.168.14.115IP地址通常为4个字节,简称 ...
- 通过队列实现进程间的通信(使用阻塞方式调用func函数)
#_author:来童星#date:2019/12/17#通过队列实现进程间的通信from multiprocessing import Poolimport osimport timedef fun ...
- 分页工具一Pageable与Page
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Page; 1.Page ...
- JAVA Java中@Override的作用
@Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处: 1.可以当注释用,方便阅读: 2.编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错.例 ...
- 线段树区间离散化——牛客多校E
这个区间离散化把我调死了.. 总之用vector来离散化,然后叶子节点维护的是一段区间,记录下每个叶子结点的起点+长度 千万要注意下标不能弄错! #include<bits/stdc++.h&g ...