前言
os和sys模块使用起来容易模糊,写一下官方的解释。
os模块提供了一种方便的用户操作操作系统的函数方法
sys模块提供由解释器使用或者维护的变量与解释器进行交互的函数
总结: os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
导入模块
import sys
常用的属性及方法
- sys.argv
- 命令行参数List,第一个元素是当前模块名
-
import sys print(sys.argv) print(sys.modules.keys()) # 在终端运行 # 输入方式一: # (demo) D:workspacemodue>python3 bin.py # ['bin.py'] # 输入方式二: # (demo) D:workspacemodue>python3 bin.py tt aa cc # ['bin.py', 'tt', 'aa', 'cc'] # 用pycharm编辑工具的运行结果 # ['D:/workspace/modue/bin.py']
- sys.path
- 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
- sys.exit(n)
- 退出程序,正常退出时:exit(0)
- sys.version
- 获取python解释器程序的版本信息
- sys.maxint
- 最大的Int值
- sys.platform
- 返回操作系统平台的名称
- sys.modules.keys()
- 返回所有已经导入的模块列表
- sys.exc_info()
- 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
- sys.hexversion
- 获取Python解释程序的版本值,16进制格式如:0x020403F0
- sys.maxunicode
- 最大的Unicode值
- sys.modules
- 返回系统导入的模块字段,key是模块名,value是模块
- sys.stdout
- 标准输出
- sys.stdin
- 标准输入
- sys.stderr
- 错误输出
- sys.exc_clear()
- 用来清除当前线程所出现的当前的或最近的错误信息
- sys.exec_prefix
- 返回平台独立的python文件安装的位置
- sys.byteorder
- 本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'
- sys.copyright
- 记录python版权相关的东西
- sys.api_version
- 解释器的C的API版本
sys.stdin,sys.stdout,sys.stderr
stdin , stdout , 以及stderr 变量包含与标准I/O 流对应的流对象. 如果需要更好地控制输出,而print 不能满足你的要求, 它们就是你所需要的. 你也可以替换它们, 这时候你就可以重定向输出和输入到其它设备( device ), 或者以非标准的方式处理它们
我们常用print和raw_input来进行输入和打印,那么
print 和 raw_input是如何与标准输入/输出流建立关系的呢?其实Python程序的标准输入/输出/出错流定义在sys模块中,分别 为: sys.stdin,sys.stdout, sys.stderr
下列的程序也可以用来输入和输出是一样的:
import sys sys.stdout.write('HelloWorld!') print 'Please enter yourname:', name=sys.stdin.readline()[:-1] print 'Hi, %s!' % name
那么sys.stdin, sys.stdout, stderr到底是什么呢?我们在Python运行环境中输入以下代码:
import sys for f in (sys.stdin,sys.stdout, sys.stderr): print f输出为:
<open file'<stdin>', mode 'r' at 892210>
<open file'<stdout>', mode 'w' at 892270>
<open file'<stderr>', mode 'w at 8922d0
而Python程序的在Shell中的I/O重定向与本文开始时举的DOS命令的重定向完全相同,其实这种重定向是由Shell来提供的,与Python 本身并无关系。那么我们是否可以在Python程序内部将stdin,stdout,stderr读写操作重定向到一个内部对象呢?答案是肯定的。
Python提供了一个StringIO模块来完成这个设想,比如:
from StringIO import StringIO import sys buff =StringIO() temp =sys.stdout #保存标准I/O流 sys.stdout =buff #将标准I/O流重定向到buff对象 print 42, 'hello', 0.001 sys.stdout=temp #恢复标准I/O流 print buff.getvalue()
例子:
做一个最次的进度条
需要了解的:
sys.stdout.write("#") # print就是根据这个语句实现的。
它会把所有的要显示的内容放到一个缓存里,会等所以内容写好了之后,再显示,所以看不到我们想要的效果。
import time, sys for i in range(10): sys.stdout.flush() sys.stdout.write("#") time.sleep(0.1)
我们用sys.stdout.flush()来刷新缓存,就是不等了,直接显示,有多少显示多少。可是试试不加的效果。
关于sys你需要知道的
临时修改环境变量
当我们修改sys.path的时候,它是一个列表,可以append一个绝对路径,但是这样不好,因为写死了,也就是说随便换一换存放路径就不可以用,所以,我们一般不这样写,而是通过os来配合加入路径。
首先我们要了解__file__。
__file__:显示的时候是一个绝对路径,而其实只取出来当前模块的名字。前面的一堆是pycharm加上的,这些后面再说,这里我们只需要知道pycharm中的__file__和sys.path和终端中的是不一样的。
下面是目录结构:
我们的目标就是将demo文件夹加入到环境变量中,方便后面的导包。
因为bin.py是启动文件,在bin.py中加入
import sys, os print(__file__) # D:/workspace/modue/demo/modue2.py print(os.path.abspath(__file__)) # D:workspacemoduedemomodue2.py print(os.path.dirname(os.path.abspath(__file__))) # D:workspacemoduedemod BASE_DIR = os.path.dirname(os.path.abspath(__file__)) print(os.path.join(BASE_DIR, 'demo')) # D:workspacemoduedemo sys.path.append(BASE_DIR) print(sys.path)
因为在终端中我们取到的是文件名,为了避免后续的麻烦,这里用os.path.abspath找到当前文件的绝对路径,然后用os.path.dirname取出当前路径下的上级路径,然后通过os.path.join将路径拼接,再加入sys.path就完成了临时的环境变量的添加。
pycharm为我们挖的坑
sys.path的坑
import sys print(sys.path) # pycharm中运行的结果 # ['D:\workspace\modue\demo', 'D:\workspace\modue', 'C:\Users\TQ\demo\Scripts\python35.zip', 'C:\Python35\DLLs', 'C:\Python35\lib', 'C:\Python35', 'C:\Users\TQ\demo', 'C:\Users\TQ\demo\lib\site-packages', 'C:\Users\TQ\demo\lib\site-packages\setuptools-28.8.0-py3.5.egg'] # 终端中运行的结果 # ['D:\workspace\modue\demo', 'C:\Users\TQ\demo\Scripts\python35.zip', 'C:\Python35\DLLs', 'C:\Python35\lib', 'C:\Python35', 'C:\Users\TQ\demo', 'C:\Users\TQ\demo\lib\site-packages', 'C:\Users\TQ\demo\lib\site-packages\setuptools-28.8.0-py3.5.egg']
后面的不用看,就看每个列表的前两个就可以看出问题来,使用pycharm会将项目的根目录自动加入环境变量中,而解释器不会。
还有一个坑就是在pycharm中,我们用__file__显示的时候,它会给修改为绝对路径,而解释器运行的时候不会,只是显示文件名,这也是我们在修改临时变量的时候加入os.path.absname来获得文件绝对路径的原因。