sys 模块主要负责与 Python 解释器进行交互,该模块提供了一系列用于控制 Python 运行环境的函数和变量。
对象名称 |
对象说明 |
sys.argv |
命令行参数List,第一个元素是程序本身路径 |
sys.path |
返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 |
sys.modules |
返回系统导入的模块字段,key是模块名,value是模块 |
sys.exc_info() |
获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息 |
sys.exit(n) |
退出程序,正常退出时exit(0) |
sys.hexversion |
获取Python解释程序的版本值,16进制格式如:0x020403F0 |
sys.version |
获取Python解释程序的版本信息 |
sys.platform |
返回操作系统平台名称 |
sys.stdout |
标准输出 |
sys.stdout.write() |
标准输出内容 |
sys.stdout.writelines() |
无换行输出 |
sys.stdin |
标准输入 |
sys.stdin.read() |
输入一行 |
sys.stderr |
错误输出 |
sys.exc_clear() |
用来清除当前线程所出现的当前的或最近的错误信息 |
sys.exec_prefix |
返回平台独立的python文件安装的位置 |
sys.byteorder |
本地字节规则的指示器 |
sys.copyright |
记录python版权相关的东西 |
sys.api_version |
解释器的C的API版本 |
sys.version_info |
返回你当前所使用的Python版本号 |
sys.getdefaultencoding() |
返回当前你所用的默认的字符编码格式 |
sys.getfilesystemencoding() |
返回将Unicode文件名转换成系统文件名的编码的名字 |
sys.builtin_module_names |
Python解释器导入的内建模块列表 |
sys.executable |
Python解释程序路径 |
sys.getwindowsversion() |
获取Windows的版本 |
sys.stdin.readline() |
从标准输入读一行 |
sys.setdefaultencoding() |
用来设置当前默认的字符编码(详细使用参考文档) |
sys.displayhook(value) |
如果value非空,这个函数会把他输出到sys.stdout(详细使用参考文档) |
返回一个具名元组,python命令行的参数状态,这些属性是只读的:
flags.debug |
-d |
flags.inspect |
-i |
flags.interactive |
-i |
flags.isolated |
-I |
flags.optimize |
-O 或 -OO |
flags.dont_write_bytecode |
-B |
flags.no_user_site |
-s |
flags.no_site |
-S |
flags.ignore_environment |
-E |
flags.verbose |
-v |
flags.bytes_warning |
-b |
flags.quiet |
-q |
flags.hash_randomization |
-R |
flags.dev_mode |
-X dev (Python 开发模式) |
flags.utf8_mode |
-X utf8 |
flags.safe_path |
-P |
flags.int_max_str_digits |
-X int_max_str_digits (integer string conversion length limitation) |
flags.warn_default_encoding |
-X warn_default_encoding |
获取运行 Python 程序的命令行参数。其中 :
sys.argv[0] 通常就是指该 Python 程序
sys.argv[1] 代表为 Python 程序提供的第一个参数
sys.argv[2] 代表为 Python 程序提供的第二个参数
……依此类推。
#sys.py
#!/usr/bin/env python
import sys
print sys.argv[0]
print sys.argv[1]
# python sys.py argv1
sys.py
argv1
如果是通过 Python 解释器的命令行参数 -c 来执行的, argv[0] 会被设置成字符串 '-c' 。如果没有脚本名被传递给 Python 解释器, argv[0] 为空字符串。
是搜索路径列表,每个元素都是一个目录名,在使用 import 语句导入模块时,解释器就会从这些路径列表中查找指定的模块。
>>>import sys
>>>sys.path
['/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev', '/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/third_party/thriftpy', '/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev']
执行到主程序末尾,解释器自动退出,但是如果需要中途退出程序,可以调用sys.exit函数,带有一个可选的整数参数返回给调用它的程序,表示你可以在主程序中捕获对sys.exit的调用。(0是正常退出,其他为异常)
import sys
def exitfunc(value):
print value
sys.exit(0)
print "hello"
try:
sys.exit(1)
except SystemExit,value:
exitfunc(value)
print "come?”
# python exit.py
hello
1
exit()之后的代码不会被执行。
返回模块名和载入模块对应关系的字典
sys.modules
{'sys': , 'builtins': , '_frozen_importlib': , '_imp': , '_thread': , '_warnings': , '_weakref': , '_io': , 'marshal': , 'posix': , '_frozen_importlib_external': , 'time': , 'zipimport': , '_codecs': , 'codecs': , ...>}
获取当前执行环境的平台
>>>sys.platform
'darwin'
系统 |
|
---|---|
AIX |
|
Emscripten |
|
Linux |
|
WASI |
|
Windows |
|
Windows/Cygwin |
|
macOS |
|
FreeBSD | 'freebsd' |
对于 Unix 系统(除 Linux 和 AIX 外),该字符串是 Python 构建时的 uname -s
返回的小写操作系统名称,并附加了 uname -r
返回的系统版本的第一部分,如 'sunos5'
或 'freebsd8'.
在 3.8 版更改: 在 AIX 上,sys.platform 将不再包含主要版本号。 它将总是 'aix',而不是 'aix5' 或 'aix7'。
标准输入、标准输出和标准错误的 文件对象:
解释器的版本信息
>>>sys.version
'3.11.4 (main, Jul 5 2023, 09:00:44) [Clang 14.0.6 ]’
>>>sys.api_version
1013
>>>sys.version_info
sys.version_info(major=3, minor=11, micro=4, releaselevel='final', serial=0)
版本号五部分的元组: major, minor, micro, releaselevel 和 serial。 除 releaselevel 外的所有值均为整数;发布级别值则为 'alpha'
, 'beta'
, 'candidate'
或 'final'
。
设置系统的跟踪函数,使得用户在 Python 中就可以实现 Python 源代码调试器。该函数是特定于单个线程的.
跟踪函数应接收三个参数:frame、event 和 arg。frame 是当前的堆栈帧。event 是一个字符串:'call'
、'line'
、'return'
、'exception'
或 'opcode'
。arg 取决于事件类型。
每次进入 trace 函数的新的局部作用范围,都会调用 trace 函数( event 会被设置为 'call'
),它应该返回一个引用,指向即将用在新作用范围上的局部跟踪函数;如果不需要跟踪当前的作用范围,则返回 None
。
局部跟踪函数应返回对自身的引用(或对另一个函数的引用,用来在其作用范围内进行进一步的跟踪),或者返回 None
来停止跟踪其作用范围。
如果跟踪函数出错,则该跟踪函数将被取消设置,类似于调用 settrace(None)
。
这些事件具有以下含义:
'call'
表示调用了某个函数(或进入了其他的代码块)。全局跟踪函数将被调用,arg 为 None
。返回值将指定局部跟踪函数。
执行下一行代码
'return'
表示某个函数(或别的代码块)即将返回。局部跟踪函数将被调用,arg 是即将返回的值,如果此次返回事件是由于抛出异常,arg 为 None
。跟踪函数的返回值将被忽略。
'exception'
表示发生了某个异常。局部跟踪函数将被调用,arg 是一个 (exception, value, traceback)
元组,返回值将指定新的局部跟踪函数。
执行新的opcode
注意,由于异常是在链式调用中传播的,所以每一级都会产生一个 'exception'
事件。
更细微的用法是,可以显式地通过赋值 frame.f_trace = tracefunc 来设置跟踪函数,而不是用现有跟踪函数的返回值去间接设置它。当前帧上的跟踪函数必须激活,而 settrace() 还没有做这件事。注意,为了使上述设置起效,必须使用 settrace() 来安装全局跟踪函数才能启用运行时跟踪机制,但是它不必与上述是同一个跟踪函数(它可以是一个开销很低的跟踪函数,只返回 None,即在各个帧上立即将其自身禁用)。
# program to display the functioning of
# settrace()
from sys import settrace
# local trace function which returns itself
def my_tracer(frame, event, arg=None):
# extracts frame code
code = frame.f_code
# extracts calling function name
func_name = code.co_name
# extracts the line number
line_no = frame.f_lineno
print(f"trace:A {event} encountered in {func_name}() at line number {line_no} , {arg=}")
return my_tracer
# global trace function is invoked here and
# local trace function is set for fun()
def foo(a:str):
print('foo() run...')
return a+"OK."
# global trace function is invoked here and
# local trace function is set for check()
def call():
print('call() run ...')
return foo('test')
# returns reference to local
# trace function (my_tracer)
settrace(my_tracer)
call()
‘’'
trace:A call encountered in call() at line number 28 , arg=None
trace:A line encountered in call() at line number 29 , arg=None
call() run ...
trace:A line encountered in call() at line number 30 , arg=None
trace:A call encountered in foo() at line number 21 , arg=None
trace:A line encountered in foo() at line number 22 , arg=None
foo() run...
trace:A line encountered in foo() at line number 23 , arg=None
trace:A return encountered in foo() at line number 23 , arg='testOK.'
trace:A return encountered in call() at line number 30 , arg='testOK.'
‘''
从上面的例子中可以看到,当运行到return时,可以从arg获取到return后面的返回内容。
如果要获得跟踪的函数内部信息,需要对frame进行分析:
f_code
该函数对应code object(类似字节码)f_builtins
该函数内置函数f_back
调用这个函数的函数的framef_lasti
last instruction类似汇编中program counter(函数执行到哪了下一步干嘛)可以根据event设置过滤,如下面统计函数的执行时间:
import sys
import time
start_time = {}
def trace_function(frame, event, arg):
global start_time
if event == 'call':
start_time[frame] = time.time()
elif event == 'return':
end_time = time.time()
time_taken = end_time - start_time[frame]
print('Function {} took {:.2f} seconds to execute'.format(frame.f_code.co_name, time_taken))
return trace_function
def function_to_trace():
print('I am being traced!')
time.sleep(1)
sys.settrace(trace_function)
function_to_trace()
sys.settrace(None)
本函数返回的元组包含三个值,它们给出当前正在处理的异常的信息。返回的信息仅限于当前线程和当前堆栈帧。如果当前堆栈帧没有正在处理的异常,则信息将从下级被调用的堆栈帧或上级调用者等位置获取,依此类推,直到找到正在处理异常的堆栈帧为止。此处的“处理异常”指的是“执行 except 子句”。任何堆栈帧都只能访问当前正在处理的异常的信息。
如果整个堆栈都没有正在处理的异常,则返回包含三个 None
值的元组。否则返回值为 (type, value, traceback)
。它们的含义是:type 是正在处理的异常类型(它是 BaseException 的子类);value 是异常实例(异常类型的实例);traceback 是一个 回溯对象,该对象封装了最初发生异常时的调用堆栈。