Python sys模块(进阶篇)

2023-11-02

原文链接:点击打开链接

本文针对原文做了少量修改和大量的补充。。。

这篇文章主要介绍了Python标准库之sys模块使用详解,讲解了使用sys模块获得脚本的参数、处理模块、
使用sys模块操作 模块搜索路径、使用sys模块查找内建模块、使用sys模块查找已导入的模块,重定向输出以及重定向错误等使用案例。。。
sys模块提供了许多函数和变量来处理 Python 运行时环境的不同部分.
处理命令行参数:在解释器启动后, argv 列表包含了传递给脚本的所有参数, 列表的第一个元素为脚本自身的名称.
【1】使用sys模块获得脚本的参数(给程序在外部传递参数):

test.py文件:

#!usr/bin/env python
#coding:utf-8
import sys
print 'sys.argv=',sys.argv
print 'The script name is',sys.argv[0] #使用sys.argv[0]采集脚本名称
if len(sys.argv)>1:
    print 'There are',len(sys.argv)-1,'arguments!' #使用len(sys.argv)-1采集参数个数,-1为减去[0]脚本名称
    for arg in sys.argv[1:]:  #输出除了[0]外所有参数
        print arg
else:
    print 'There is no argument!'

运行结果:
song@ubuntu:~$ python test.py
sys.argv= ['test.py']
The script name is test.py
There is no argument!
song@ubuntu:~$ python test.py argument1 argument2
sys.argv= ['test.py', 'argument1', 'argument2']
The script name is test.py
There are 2 arguments!
argument1
argument2
song@ubuntu:~$

【2】如果是从标准输入读入脚本, 脚本的名称将被设置为空串。
song@ubuntu:~$ python < test.py
sys.argv= ['']
The script name is 
There is no argument!

【3】如果把脚本作为字符串传递给python (在命令行下选用 -c 选项), 脚本名会被设置为 "-c"。
song@ubuntu:~$ python  -c "import sys;print sys.argv;print sys.argv[0]" arg1 arg2
['-c', 'arg1', 'arg2']
-c
song@ubuntu:~$
如果大家不明白,可以参考下man python
SYNOPSIS
       python [ -d ] [ -E ] [ -h ] [ -i ] [ -m module-name ] [ -O ]
              [ -Q argument ] [ -S ] [ -t ] [ -u ]
              [ -v ] [ -V ] [ -W argument ] [ -x ]
              [ -c command | script | - ] [ arguments ]

处理模块:
我们在使用模块的某一个功能前,需要用import,__import__命令导入。
那我们在执行import module_name的时候,python内部发生了什么呢?
简单的说,就是搜索module_name。根据sys.path的路径来搜索module.name

>>> import sys
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
>>>
我们以后写好的模块就可以放到上面的某一个目录下,便可以正确搜索到了。

当然也可以添加自己的模块路径。sys.path.append(“my module path”)。

>>> sys.path.append('my module path')
>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', 'my module path']
>>> 

path列表是一个由目录名构成的列表, Python 从中查找扩展模块( Python 源模块, 编译模块,或者二进制扩展).
启动 Python 时,这个列表根据内建规则, PYTHONPATH 环境变量的内容, 以及注册表( Windows 系统)等进行初始化.
由于它只是一个普通的列表, 你可以在程序中对它进行操作。。。

【4】操作sys模块中的搜索路径:

path.py文件:

#!usr/bin/env python
#coding:utf-8
import sys
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
sys.path.insert(0,'/tmp')  #将路径插入到path[0]中
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
sys.path=[]  #删除path中所有路径
print 'sys.path=',sys.path
print 'sys.path has',len(sys.path),'members.'
#上述对sys.path的修改,仅仅在当前文件中有效,并不会修改python标准库中的sys模块。。。
运行结果:
song@ubuntu:~$ python path.py
sys.path= ['/home/song', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
sys.path has 12 members.
sys.path= ['/tmp', '/home/song', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PILcompat', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
sys.path has 13 members.
sys.path= []
sys.path has 0 members.

【5】使用sys模块查找内建模块:
builtin_module_names 元组包含 Python 解释器中所有内建模块的名称

find_module.py文件:

def find_module(module):
    print module,'=>',
    if module in sys.builtin_module_names: #查找内建模块是否存在
        print '<biultin>'
    else:
        mod=__import__(module) #非内建模块 输出模块路径
        print mod.__file__

import sys
print 'sys.builtin_module_names=',sys.builtin_module_names
find_module('os')
find_module('sys')
find_module('string')
find_module('strop')
find_module('zlib')
运行结果:
song@ubuntu:~$ python find_module.py
sys.builtin_module_names= ('__builtin__', '__main__', '_ast', '_bisect', '_codecs', '_collections', '_functools', '_heapq', '_io', '_locale', '_md5', '_random', '_sha', '_sha256', '_sha512', '_socket', '_sre', '_struct', '_symtable', '_warnings', '_weakref', 'array', 'binascii', 'cPickle', 'cStringIO', 'cmath', 'errno', 'exceptions', 'fcntl', 'gc', 'grp', 'imp', 'itertools', 'marshal', 'math', 'operator', 'posix', 'pwd', 'select', 'signal', 'spwd', 'strop', 'sys', 'syslog', 'thread', 'time', 'unicodedata', 'xxsubtype', 'zipimport', 'zlib')
os => /usr/lib/python2.7/os.pyc
sys => <biultin>
string => /usr/lib/python2.7/string.pyc
strop => <biultin>
zlib => <biultin>
song@ubuntu:~$

【6】使用sys模块查找已导入的模块(sys.modules):
This is a dictionary that maps module names to modules which have already been loaded.
This can be manipulated to force reloading of modules and other tricks.
Python.org手册里已经说的很明白了。
modules 字典包含所有加载的模块。 import 语句在从磁盘导入内容之前会先检查这个字典。
Python 在处理你的脚本之前就已经导入了很多模块.

>>> import sys
>>> type(sys.modules)
<type 'dict'>
>>> sys.modules.keys()
['copy_reg', 'sre_compile', '_sre', 'encodings', 'site', '__builtin__', 'sysconfig', '__main__', 'encodings.encodings',
 'abc', 'posixpath', '_weakrefset', 'errno', 'encodings.codecs', 'sre_constants', 're', '_abcoll', 'types', '_codecs', 
'encodings.__builtin__', '_warnings', 'genericpath', 'stat', 'zipimport', '_sysconfigdata', 'warnings', 'UserDict', 
'encodings.utf_8', 'sys', 'codecs', 'readline', '_sysconfigdata_nd', 'os.path', 'sitecustomize', 'signal', 'traceback',
 'linecache', 'posix', 'encodings.aliases', 'exceptions', 'sre_parse', 'os', '_weakref']
>>> len(sys.modules.keys())
43
>>>

【7】使用sys模块获得当前平台:
sys.platform  返回当前平台,例如: "win32" "linux2" 等

# windows下:
>>> import sys
>>> sys.platform
'win32'
# Linux下:
>>> import sys
>>> sys.platform
'linux2'
>>>
大家都知道,当今的程序比较流行的是跨平台。简单的说就是这段程序既可以在windows下运行,
换到linux下也可以不加修改的运行起来,此时,sys.platform 就派上用场了。
假设,我们想实现一个清除终端程序,linux下用clear, windows下用cls
clean.py文件:

#!usr/bin/env python
#coding:utf-8
import sys,os
osType=sys.platform
if osType=='linux' or osType=='linux2':
    command='clear'
else:
    command='cls'
os.system(command)
【8】处理标准输出/输入:
标准输出和标准错误 (通常缩写为 stdout 和 stderr) 是内建在每一个 UNIX 系统中的管道。
当你 print 某些东西时,结果前往 stdout 管道;
例如:

>>> for i in range(3):
...     print 'hello python'
... 
hello python
hello python
hello python
>>> import sys
>>> for i in range(3):
...     sys.stdout.write('hello python\n')
... 
hello python
hello python
hello python
【9】当你的程序崩溃并打印出调试信息 (例如 Python 中的 traceback (错误跟踪) ) 的时候,信息前往 stderr 管道。。

>>> l=[1,2]
>>> print l[10]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
stdout 是一个类文件对象;调用它的 write 函数可以打印出你给定的任何字符串。
实际上,这就是 print 函数真正做的事情;它在你打印的字符串后面加上一个硬回车,然后调用 sys.stdout.write 函数。
在最简单的例子中,stdout 和 stderr 把它们的输出发送到相同的地方。
和 stdout 一样,stderr 并不为你添加硬回车;如果需要,要自己加上。。。
stdout 和 stderr 都是类文件对象,但是它们都是只写的(它们都没有 read 方法,只有 write 方法)
由于它们是类文件对象,因此你可以将其它任何 (类) 文件对象赋值给它们来重定向其输出。
【10】重定向输出:

>>> import sys
>>> print 'hello python'     #标准输出
hello python
>>> saveout=sys.stdout       #在重定向前保存stdout,之后你还可以将其设回正常
>>> flog=open('out.log','w') #打开一个新文件用于写入。如果文件不存在,将会被创建。如果文件存在,将被覆盖。
>>> sys.stdout=flog          #所有后续的输出都会被重定向到刚才打开的新文件上。
>>> print  'This message will be logged instead of displayed'
# 这样只会将输出结果“打印”到日志文件中;屏幕上不会看到输出。。。
>>> flog.close()             #关闭日志文件
>>> sys.stdout=saveout       #将 stdout 设回原来的方式。
>>> print 'ok'               #标准输出(已经将stdout恢复到原来的方式)
ok
>>> f=open('out.log','r')
>>> f.read() #注意最后的'\n'(说明print会在要打印的字符串后面加上一个硬回车)
'This message will be logged instead of displayed\n'
【11】重定向错误信息:

>>> import sys
>>> flog=open('error.log','w')# 打开要存储调试信息的日志文件。
>>> sys.stderr=flog #将新打开的日志文件的文件对象 赋值给stderr,以重定向标准错误。
>>> raise Exception, 'this error will be logged'
# 引发一个异常,没有在屏幕上打印出任何东西,所有正常的跟踪信息已经写进error.log
#还要注意我们既没有显式关闭日志文件,也没有将 stderr 设回最初的值。
#这样挺好,因为一旦程序崩溃 (由于引发的异常),Python 将替我们清理并关闭文件 

【12】打印到 stderr:
向标准错误写入错误信息是很常见的,所以有一种较快的语法可以立刻导出信息

>>> print 'hello python'   #标准输出
hello python
>>> import sys
>>> print >> sys.stderr,'hello python' #将单个print语句重定向到stderr,而且不影响后面的print语句
hello python
>>> 
【13】print 语句的快捷语法可以用于写入任何打开的文件 (或者是类文件对象)。

>>> f=open('print.txt','w')
>>> print >>f,'hello python' #将单个print语句重定向到打开的文件对象f
>>> f.close()
>>> f=open('print.txt','r')
>>> f.read()
'hello python\n' # print会在要打印的字符串后面加上一个硬回车
>>> f.close()
【14】使用sys模块退出程序:
执行至主程序的末尾时,解释器会自动退出. 但是如果需要中途退出程序,我们可以调用sys.exit 函数,
它带有一个可选的整数参数返回给调用它的程序. 这意味着你可以在主程序中捕获对sys.exit 的调用。
(注:0是正常退出,其他为不正常,可抛异常事件供捕获!)

>>> import sys
>>> sys.exit(1)
song@ubuntu:~$ 
#注意 sys.exit 并不是立即退出,而是引发一个 SystemExit 异常。
#这意味着我们可以在主程序中捕获对 sys.exit 的调用
捕获sys.exit调用(1):
exit.py文件:

#!usr/bin/env python
#coding:utf-8
import sys
print 'hello python'
try:
    sys.exit(1)
except SystemExit: #捕获到退出异常,,,程序不会退出,后边的语句会继续执行。。。
    pass           #捕获后不做任何操作
print 'ok'
运行结果:
song@ubuntu:~$ python exit.py
hello python
ok

捕获sys.exit调用(2):
exitfunc.py文件:
#!usr/bin/env python
#coding:utf-8
import sys
def exitfunc(value):
    '''clear function'''
    print value
    sys.exit(0) #没有去捕获 抛出的SystemExit异常,执行到该语句时退出解释器
print 'hello!'
try:
    sys.exit(1)  #抛出的SystemExit异常,被成功捕获
except SystemExit,value:
    exitfunc(value)
print 'not out!' #该语句不会执行

输出结果:
song@ubuntu:~$ python exitfunc.py
hello!
1
song@ubuntu:~$
以下是python.org库参考手册中,摘抄来的,供参考。
Exit from Python. This is implemented by raising the SystemExit exception, 
so cleanup actions specified by finally clauses of try statements are honored, 
and it is possible to intercept the exit attempt at an outer level.
The optional argument arg can be an integer giving the exit status (defaulting to zero),
or another type of object. If it is an integer, zero is considered “successful termination” 
and any nonzero value is considered “abnormal termination” by shells and the like.
Most systems require it to be in the range 0-127, and produce undefined results otherwise. 
Some systems have a convention for assigning specific meanings to specific exit codes,
but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors 
and 1 for all other kind of errors. If another type of object is passed, 
None is equivalent to passing zero, and any other object is printed to sys.stderr 
and results in an exit code of 1. In particular,
sys.exit("some error message") is a quick way to exit a program when an error occurs.
大概意思是说,sys.exit从python程序中退出,将会产生一个systemExit异常,可以为此做些清除除理的工作。
这个可选参数默认正常退出状态是0,以数值为参数的范围为:0-127。其他的数值为非正常退出,
还有另一种类型,在这里展现的是strings对象类型。
如果准备在退出前自己清理一些东西(比如删除临时文件), 
你可以配置一个 "退出处理函数"(exit handler), 它将在程序退出的时候自动被调用。。
另一种捕获sys.exit调用的方法:
exit_handler.py文件:

#!usr/bin/env python
#coding:utf-8
import sys
def exitfunc():
    print 'exit is done!'
sys.exitfunc=exitfunc # 设置退出时要自动调用的函数
print 'hello world'
sys.exit(1) # 退出,后边的语句不再执行( 但在退出之前会自动调用exitfunc() )
print 'ok'  #该语句不会执行
运行结果:
song@ubuntu:~$ python exit_handler.py
hello world
exit is done!


(完)


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python sys模块(进阶篇) 的相关文章

随机推荐

  • Myeclipse启动tomcat的debug模式,总是跳到Class.class里面的解决办法

    方法一 在工作界面 点window菜单栏 选中Preperences 在General选项卡中的key节点下 找到快捷键输入栏 在type filter text中输入remove 下面自能提示中就会出现Remove all breakpo
  • 物联网ARM开发-4协议-单总线应用温湿度传感器

    前言 STM32 虽然内部自带了温度传感器 但是因为芯片温升较大等问题 与实际温度差别较大 所以 本章我们将向大家介绍如何通过 STM32 来读取外部数字温度传感器的温度 来得到较 为准确的环境温度 在本章中 我们将学习使用单总线技术 通过
  • vue项目国际化(多语言)

    记录一下笔记 以下vue项目案例使用vue cli搭建 一 安装依赖 1 使用npm命令安装所需依赖vue i18n 此demo安装的版本为vue i18n 8 24 2 安装命令 npm i vue i18n 8 24 2 2 安装完成之
  • SQL删除表语句

    1 普通删除表语句 必须同时满足如下两个条件 该表必须存在 若不存在则报错 要删除的表不能存在与其他表的约束 否则SQL会报错 DROP TABLE 要删除的表名 2 判断式删除表语句 必须满足如下条件 被删除的表不一定存在 若不存在则不删
  • CentOS8安装Docker

    文章目录 1 背景简介 2 错误提示 3 问题分析 4 解决方法 1 背景简介 最近用上了VULTR机器 默认使用了CentOS8 正好尝尝鲜 尝试安装Docker时出现了错误 故及时记录一下 方面其他同学 2 错误提示 Problem p
  • 智能化漏洞挖掘技术总结

    全文基于 从自动化到智能化 软件漏洞挖掘技术进展 进行提炼 总结 修改 1 静态漏洞挖掘技术 1 1面向源代码 面向源代码的漏洞挖掘主要采用基于中间表示的分析和基于逻辑推理的分析技术 基于中间表示的分析技术主要包括数据流分析 控制流分析 污
  • SD卡的操作模式及切换

    目录 SD卡的操作模式及切换 SD卡的操作模式 卡识别模式 数据传输模式 SD卡的操作模式及切换 SD卡的操作模式 SD卡有多个版本 STM32控制器目前最高支持 Physical Layer Simplified Specificatio
  • k8s安装禁用swap分区k

  • Apache Solr入门教程(初学者之旅)

    Apache Solr入门教程 初学者之旅 写在前面 本文涉及solr入门的各方面 请逐行阅读 相信能帮助你对solr有个清晰全面的了解并能简单实用 在Apache Solr初学者教程的这个例子中 我们将讨论有关如何安装最新版本的Apach
  • vue配置生产环境.env.production、测试环境.env.development

    静下来 慢慢看 首先 我们需要搭建一个项目 依赖包会自动下载好 无需自己 npm i env 无论什么环境都会加载 env production 生产环境加载 env development 测试开发环境加载 我们下面的例子分开来写 只用
  • Vue的事件处理,点击事件

    目录 1 v on click 绑定属性示例 2 v on click 绑定方法示例 3 v on click 绑定特殊变量示例 4 事件处理的修饰符 按键修饰符 v model表单修饰符 v bind指令修饰符 监听DOM事件使用的是v
  • Tenserflow学习(一)——MNIST数据集分类简单版本

    编写简单的单层网络实现MNIST数据集分类 代码如下 import tensorflow as tf from tensorflow examples tutorials mnist import input data 载入数据 one h
  • 【刷题版】掌握算法的一揽子计划——深度优先搜索和回溯

    文章目录 深搜和回溯总结 基本概念 常见例题 自然数的拆分 排列型枚举 全排列 I 全排列 II 组合型枚举 组合 I 组合 II N皇后问题 一些简单的树和图上的问题 二叉树的遍历 二叉树的所有路径 岛屿的最大面积 参考资料 深搜和回溯总
  • 嵌入式图形库开发绚丽界面(lvgl、emwin、awtk)

    前言 早些年的单片机开发中 很多都是使用文字菜单界面 这种界面让人感觉非常的朴实无华 内容言简意赅 如果使用图形库进行开发 你的产品一下子就让别人觉得有点高级 更容易去接收它 对于现在来说 很多的嵌入式图形库都可以做出绚丽的界面 占用RAM
  • el-select下拉框有数据无显示

    问题描述 vue element项目开发中 出现有数据无显示 或者下拉框错位的情况
  • python高级调试技巧(一)——原生态的pdb调试

    声明 本文所讲的调试是指不附带任何工具的调试 我们平时使用vs code pycharm进行调试 包括设置断点 单步执行 多步执行等操作都是IDE设置好的 本文不考虑这些 使用原生态的python调试器 不需要任何IDE开发环境 pdb是p
  • ue4.24调通了shader文档

    先上图 有几个感慨 1 ue4文档不与时俱进 所以还要看源码或者例子 这个就是按照源码插件依葫芦画瓢进行的 2 shader加载时机 按照build cs进行 要不会崩溃 启动编辑器之后才加载 3 蓝图要熟 因为要给蓝图用 所以 还要学学
  • 生产者消费者模型你知道多少

    背景 进入正题之前先说点故事 从最开始学java的那里开始 我是从08年下半年开始学Java 在 我的六年程序之路 中提到了一些 当时比较简单 每天看尚学堂的视频 对于初学者而言看视频好一些 然后写代码 比较清楚的记得马士兵讲到生产者消费者
  • 大数据应用——总结与反思

    1 谈谈你对大数据行业的认识 目前对应的大数据岗位有哪些 每种岗位需要掌握哪些技能水平 目前自己的差距在哪里 1 概述 对于大数据行业的认识 我的理解是 大数据是指海量数据 多样化的数据类型和高速度的数据流 传统的关系型数据库无法胜任其存储
  • Python sys模块(进阶篇)

    原文链接 点击打开链接 本文针对原文做了少量修改和大量的补充 这篇文章主要介绍了Python标准库之sys模块使用详解 讲解了使用sys模块获得脚本的参数 处理模块 使用sys模块操作 模块搜索路径 使用sys模块查找内建模块 使用sys模