sys 模块
sys 模块包括了一组非常实用的服务,内含很多函数方法和变量,用来处理 Python 运行时配置以及资源,从而可以与前当程序之外的系统环境交互,如:Python 解释器。与 os 模块相比,其更多的在于针对系统环境的交互,而 os 则操作文件目录。
使用 sys 模块
>>> import sys
>>> dir(sys)
sys 模块常见函数
sys.argv
: 命令行参数,包括脚本名称,实现从程序外部向程序传递参数sys.exit([arg])
: 程序中间的退出,arg=0 为正常退出sys.path
: 查找模块所在目录的目录名列表sys.modules
:映射模块名字到载入模块的字典sys.platform
: 获取当前系统平台sys.stdin
:标准输入流-一个类文件(file-like)对象sys.stdout
:标准输出流-一个类文件对象sys.stderr
:标准错误流-一个类文件对象sys.getdefaultencoding()
: 获取系统当前编码,一般默认为 ascii。sys.setdefaultencoding()
: 设置系统默认编码,需要reload(sys)
才能查询看到sys.getfilesystemencoding()
: 获取文件系统使用编码方式
sys.argv
sys.argv
是命令行参数,包括脚本名称,它的功能可以实现从程序外部向程序传递参数。
假设有一个名为test.py
的文件,则可以通过 import sys
和 print(sys.argv[number])
两句来实现。number=0 为这个脚本的名字,1,2,…
则为命令行下传递的参数。
如test.py脚本内容如下:
import sys
print(sys.argv[0])
print(sys.argv[1])
print(sys.argv[2])
print(sys.argv[3])
那么要实现参数传递即可采用 >>> python test.py arg1 arg2 arg3
实现。下文会结合 sys.path
给出一个示例。上述命令的输出结果为:
test.py
arg1
arg2
arg3
sys.exit([arg])
执行至主程序的末尾时,解释器会自动退出。但如果需要中途退出程序,可以调用sys.exit()
函数来实现。它带有一个可选的整数参数返回给调用它的程序。这意味着你可以在主程序中捕获对sys.exit()
的调用。(0为正常退出,其他为不正常,可抛异常事件供捕获)
sys.exit()
函数运行示例如下:
import sys
sys.exit(1) # 直接退出程序
print('hello')
sys.path
sys.path
的功能是获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到。
示例:
>>> import sys
>>> sys.path
['',
'D:\python310\\Scripts',
'D:\python310\\python36.zip',
'D:\python310\\DLLs',
'D:\python310\\lib',
'D:\python310',
'C:\\Users\\Administrator\\AppData\\Roaming\\Python\\Python36\\site-packages',
'D:\python310\\lib\\site-packages',
'D:\python310\\lib\\site-packages\\setuptools-39.1.0-py3.6.egg',
'D:\python310\\lib\\site-packages\\pip-10.0.1-py3.6.egg',
'D:\python310\\lib\\site-packages\\win32',
'D:\python310\\lib\\site-packages\\win32\\lib',
'D:\python310\\lib\\site-packages\\Pythonwin',
'D:\python310\\lib\\site-packages\\IPython\\extensions',
'C:\\Users\\Administrator\\.ipython']
可以采用 sys.path.append("自定义模块路径")
增加模块搜索路径(也可以用 sys.path.insert
进行列表插入)。以上列出的模块目录,在 python 执行import module_name
时,会依次从上述列出的路径来搜索对应的模块。如有需要手动添加模块,可放入对应的路径中,如无必要建议不要手动添加路径。.
代表当前文件目录。
上问提到的sys.argv
参数传递示例如下:
输入:
import sys
print('当前 Python PATH 路径有以下内容:')
for path in sys.path:
print(path)
输出:
当前 Python PATH 路径有以下内容:
F:\进阶部分
F:\进阶部分
D:\python310\python36.zip
D:\python310\DLLs
D:\python310\lib
D:\python310
C:\Users\Administrator\AppData\Roaming\Python\Python36\site-packages
D:\python310\lib\site-packages
D:\python310\lib\site-packages\setuptools-39.1.0-py3.6.egg
D:\python310\lib\site-packages\pip-10.0.1-py3.6.egg
D:\python310\lib\site-packages\win32
D:\python310\lib\site-packages\win32\lib
D:\python310\lib\site-packages\Pythonwin
C:\Program Files\JetBrains\PyCharm 2018.2.5\helpers\pycharm_matplotlib_backend
sys.modules
下面部分内容均为演示
sys.modules
是一个全局字典,该字典是 python 启动后就加载在内存中。每当导入新的模块时,sys.modules
将自动记录该模块。当第二次再导入该模块时,python 会直接到字典中查找,从而加快了程序运行的速度。它拥有字典所拥有的一切方法。
示例:
import sys
print(sys.modules.keys()) # 列出所有的模块名
print(sys.modules['os']) # 列出指定模块如 os 模块所在路径
print(sys.modules.values()) # 列出所有模块所在路径
sys.platform
sys.platform
语句用于查看当前平台,如 win32、linux 等。
>>> sys.platform
'win32'
标准数据流
sys.stdin/sys.stdout/sys.stderr 变量包含与标准I/O流对应的流对象。如果需要更好地控制输出,而 print 不能满足你的要求,它们就是你所需要的。你也可以替换它们,这时候你就可以重定向输出和输入到其它设备(device),或者以非标准的方式处理它们。
我们平时的输入输出方式通过 input/print 实现,即
print('Hello World!')
print('Hi, %s!' % input('Please enter your name:'))
上述中,键盘键入的信息则为标准输入,屏幕输出的结果则为标准输出。而上述的例子,与下文采用 sys.stdin/sys.stdout 的结果是一致的。
import sys
sys.stdout.write('Hello World!')
print('请输入你的名字:')
name = sys.stdin.readline()[:-1]
print('Hi, %s!' % name)
输入 for f in (sys.stdin, sys.stdout, sys.stderr): print(f)
可查看属性信息。
>>> import sys
>>> for f in (sys.stdin, sys.stdout, sys.stderr): print(f)
...
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>
注:通过 Python Shell 输出结果与上述有所出入,但上述要表述的信息正确。
stdin/stdout/stderr 在 Python 中都是文件属性的对象,在 Python 启动时自动与 Shell 环境中的标准输入/输出/出错关联。与标准输出 print 和标准出错所不同的是,stdin/stdout/stderr 三者不具备自动回车功能,而标准输入输出则默认自动加了回车。stdin 只读,stdout 和 stderr 只写。
使用 sys 重定向输出
代码如下:
import sys
print('Dive in') # 标准输出
saveout = sys.stdout # 终在重定向前保存 stdout,这样的话之后你还可以将其设回正常
fsock = open('out.log', 'w') # 打开一个新文件用于写入。如果文件不存在,将会被创建。如果文件存在,将被覆盖。
sys.stdout = fsock # 所有后续的输出都会被重定向到刚才打开的新文件上。
print('This message will be logged instead of displayed') # 这样只会将输出结果“打印”到日志文件中;屏幕上不会看到输出
sys.stdout = saveout # 在我们将 stdout 搞乱之前,让我们把它设回原来的方式。
fsock.close() # 关闭日志文件。