前言
本文是根据python官方教程中标准库模块的介绍,自己查询资料并整理,编写代码示例做出的学习笔记。
根据模块知识,一次讲解单个或者多个模块的内容。
教程链接:https://docs.python.org/zh-cn/3/tutorial/index.html
错误输出重定向和程序终止
在Python中,没有单独用于错误输出重定向和程序终止的模块,主要是通过sys模块和os模块一起实现。
这里我们先把错误输出重定向和程序终止的功能讲一下,然后再主要讲讲sys模块。
实现功能主要通过下面几个函数:
- sys.stdout :标准输出
- sys.stderr: 标准错误流
- sys.exit([arg]): 终止当前程序,可选地传入一个参数作为退出状态码。默认情况下,0表示成功,非零值通常表示异常终止。当我们调用这个函数的时候,即表示我们需要终止当前程序的运行。这个函数用于指示程序已经成功完成其任务并需要干净、有序地关闭,是程序流程控制中的一个重要手段。
- os.dup(fd): 复制指定的文件描述符 fd。几个常见的文件描述符有:0-标准输入(stdin),1-标准输出(stdout),2-标准错误(stderr)
- os.dup2(fd1, fd2): 用于复制文件描述符fd1到fd2,常用于重定向输出流。
import sys
import os# 创建或打开一个文件用于错误输出重定向
with open('error.log', 'w') as f:original_stderr_fd = os.dup(2)try:os.dup2(f.fileno(), 2)# 模拟发生错误的情况raise ValueError("这是一个错误示例")except Exception as e:# 显式打印错误信息到重定向后的stderr(即error.log)print(f"捕获到错误: {e}", file=sys.stderr)finally:# 恢复标准错误到初始状态os.dup2(original_stderr_fd, 2)os.close(original_stderr_fd)# 由于使用了with语句,文件会在此自动关闭,但显式调用flush确保数据被立即写入f.flush()# 使用sys.exit终止程序,假设一切正常,使用0作为退出状态码
sys.exit(0)
执行代码,发现目录下生了一个error.log文件,并且文件被写入了我们手动抛出的错误信息。
在上面的代码中:
-
使用w的模式,创建了一个error.log的文件。这个文件后面用来复制文件描述符重定向输出流。
-
使用os.dup(2)函数,复制了stderr的文件描述符到变量original_stderr_fd 。注意dup函数的输出的新文件描述符指向与旧文件描述符相同的底层文件,也就是说通过新旧两个文件描述符进行的读写操作会影响同一个文件资源。
-
使用os.dup2(fd1,fd2)函数。这个函数执行的结果就是 fd2 被重定向 了,使其 指向了 fd1 当前所指向的文件或资源,并且断开之前指向的资源。这意味着之后对 fd2 的任何读写操作都将作用于原本 fd 指向的文件或资源上。对于代码来说,就是对stderr的读写会复制到error.log文件上。
-
手动抛出了一个错误信息,让异常处理模块工作。
-
把捕获的错误信息显示的打印到stderr,由于3的存在,信息会复制到error.log文件中。
-
使用os.dup2将之前备份的原始标准错误文件描述符original_stderr_fd复制到标准错误文件描述符(2),以恢复标准错误输出。这里要和23一起看。我们先通过2复制出了original_stderr_fd,由于函数dup的特性original_stderr_fd和stderr指向同一个资源,又通过3,把error.log复制给了stderr,由于函数dup2的特性,stderr和original_stderr_fd断开关联,和error.log关联上。最后把original_stderr_fd再通过dup2复制会stderr,这个时候stderr和error.log又断开。而original_stderr_fd原本就是stderr复制出的文件描述符。简单理解为 a=b,b=c,b=a这种操作。
-
关闭一些资源
-
退出程序,大家可以看到运行输出框中有一行字:进程已结束,退出代码为0。如果你exit函数的参数传1,那么这里展示退出代码为1。
有点难理解,我也懵挺久,感觉后面还得研究研究。觉得头痛可以先跳过吧,有需要用到的时候再仔细专研一下。
字符串模式匹配
re模块(正则表达式模块),是Python中最常用的字符串模式匹配模块。正则表达式是一种强大的文本处理工具,能够进行复杂的字符串匹配和替换操作。
常用函数
- re.compile(pattern[, flags]):编译正则表达式模式,创建一个正则表达式对象。
- match(pattern, string[, flags]):尝试从字符串的起始位置匹配模式,返回Match对象或None。
- search(pattern, string[, flags]):扫描整个字符串,寻找模式的第一个匹配项,返回Match对象或None。
- findall(pattern, string[, flags]):返回字符串中所有非重叠匹配项的列表。
- sub(pattern, repl, string[, count, flags]):将字符串中匹配到的模式替换为指定的字符串或函数返回值。
使用
import re
# 编译正则表达式
pattern = re.compile(r'\d+')# 使用match方法从字符串开始处匹配数字
match_result = pattern.match('123abc')
if match_result:print("Match found:", match_result.group())
else:print("No match at the start.")# 使用search在整个字符串中查找数字
search_result = pattern.search('abc123def')
if search_result:print("Search found:", search_result.group())# 使用findall找到所有数字
findall_results = pattern.findall('abc123def456ghi')
print("Find all matches:", findall_results)# 使用sub替换匹配到的数字为"number"
sub_result = pattern.sub('number', 'abc123def456ghi')
print("After substitution:", sub_result)
正则表达式的函数调用没有那么复杂,相对需要学习的是正则表达式的编写,这东西巴拉巴拉又是一大段,但是我们重点不放在这里,就略过了。
结尾
今天主要讲的内容没有特别要注意的地方,因为第一个有点抽象,第二个重点不在于函数的应用。但是还是要认真看看,起码要知道有这个模块,能实现哪些功能,不然真遇到情况了还不知道用啥。