doc: 阅读python文档

This commit is contained in:
asahi
2025-08-17 05:28:33 +08:00
parent 68c21c80d1
commit 0e2445ccbf

View File

@@ -57,14 +57,19 @@
- [dir](#dir) - [dir](#dir)
- [package](#package) - [package](#package)
- [from ... import \*](#from--import-) - [from ... import \*](#from--import-)
- [异常处理](#异常处理) - [Errors and Exceptions](#errors-and-exceptions)
- [抛异常](#抛异常) - [Syntax Errors](#syntax-errors)
- [捕获异常后重新抛出异常](#捕获异常后重新抛出异常) - [Exceptions](#exceptions)
- [主动抛出异常](#主动抛出异常) - [handling exceptions](#handling-exceptions)
- [数据存储](#数据存储) - [python异常结构](#python异常结构)
- [json.dump](#jsondump) - [rasing exception](#rasing-exception)
- [json.load](#jsonload) - [Exception Chaining](#exception-chaining)
- [http api](#http-api) - [用户自定义异常类型](#用户自定义异常类型)
- [define cleanup action](#define-cleanup-action)
- [predefined clean-up action](#predefined-clean-up-action)
- [rasing multi exceptions](#rasing-multi-exceptions)
- [except\*](#except)
- [enriching exceptions with notes](#enriching-exceptions-with-notes)
- [多线程](#多线程) - [多线程](#多线程)
- [linux命令交互](#linux命令交互) - [linux命令交互](#linux命令交互)
- [正则](#正则) - [正则](#正则)
@@ -786,123 +791,337 @@ echo.echofilter(input, output, delay=0.7, atten=4)
__all__ = ["echo", "surround", "reverse"] __all__ = ["echo", "surround", "reverse"]
``` ```
## 异常处理 ## Errors and Exceptions
在python中,可以通过如下语法来进行异常处理 在python中存在两种不同的异常,`syntax erros`和`exceptions`
### Syntax Errors
syntax errors又被称为parsing errors当parser检测到语法错误时会抛出该error
### Exceptions
在python程序执行时即使语法都正常也有可能在执行时发生异常。在程序执行时被检测到的异常被称为`exceptions`但是其时可以被处理的并不会无条件的造成fatal。
### handling exceptions
可以在程序中对特定类型的异常进行处理,示例如下所示:
```py
while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print("Oops! That was no valid number. Try again...")
```
上述示例中针对`ValueError`类型的异常进行了捕获,并提示用户输入有效的数字。但是,在上述程序实例中,用户仍然能够通过`Ctrl + C`中断该程序。
> `Ctrl + C`将会以抛出`KeyboardInterrupt`的形式表现。
try statement中可以包含多个except为不同类型的异常指定handler最多只会有一个handler被执行。并且一个except中也可以包含多个exceptions示例如下所示
```py
... except (RuntimeError, TypeError, NameError):
... pass
```
包含多个except的示例如下所示:
```py
class B(Exception):
pass
class C(B):
pass
class D(C):
pass
for cls in [B, C, D]:
try:
raise cls()
except D:
print("D")
except C:
print("C")
except B:
print("B")
```
上述示例中,会输出`B, C, D`。但是,如果修改`except B`的位置为第一位,那么输出将会变为`B, B, B`。
在except语法中除了指定异常类型外还支持指定一个变量名来捕获异常该变量中包含`args`属性,能够访问`构造该异常对象时传递的参数`,并且,异常中还定义了`__str__()`方法用于打印所有的异常参数。
为捕获的异常绑定变量的示例如下所示:
```py ```py
try: try:
# code block raise Exception('spam', 'eggs')
pass except Exception as inst:
except ErrorType1: print(type(inst)) # the exception type
# error type 1 handling code block print(inst.args) # arguments stored in .args
pass print(inst) # __str__ allows args to be printed directly,
except ErrorType2: # but may be overridden in exception subclasses
# error type 2 handling code block x, y = inst.args # unpack args
pass print('x =', x)
except Exception as result: print('y =', y)
# handle other exception types
pass
else:
# code block that no error occurs
pass
finally:
# code block executed whether exception occurs
pass
``` ```
### 抛异常 输出内容为:
#### 捕获异常后重新抛出异常 ```
如果python在捕获异常后需要重新对异常进行抛出可以使用`raise`关键字 <class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
```
#### python异常结构
`BaseException`是所有异常类的common base class而`Exception`类则是`BaseException`的子类同时也是所有非fatal异常类的base class。
对于是`BaseException`子类但是不是`Exception`子类的类,其通常代表不应当被处理的异常,抛出该类异常通常代表程序应当被终止,其包含如下类:
- `SystemExit`:由`system.exit()`抛出
- `KeyboardInterrupt`:由想要中止程序的用户触发`Ctrl + C`
`Exception`可以被用做匹配所有异常。
```py
import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error:", err)
except ValueError:
print("Could not convert data to an integer.")
except Exception as err:
print(f"Unexpected {err=}, {type(err)=}")
raise
```
`try-except`语法还支持`else``else`必须跟在所有`except`之后,其代表`try block`中没有抛出任何异常的场景。
```py
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except OSError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
```
### rasing exception
`raise`关键字支持抛出异常,示例如下
```py
raise NameError('HiThere')
```
传递给raise的必须是`Exception`的实例或是`继承自Exception的类`但传递的是类时其会使用类的默认构造器来构造Exception实例。
```py
raise ValueError # shorthand for 'raise ValueError()'
```
`raise`关键字也能用于对异常的重新抛出,示例如下:
```py ```py
try: try:
m = 10/0 raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
```
### Exception Chaining
如果在`except`处理异常时处理逻辑又抛出了异常那么其会将被处理的异常关联到新异常中并且将被处理异常包含在error msg中
```py
try:
open("database.sqlite")
except OSError:
raise RuntimeError("unable to handle error")
```
其输出如下:
```
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
open("database.sqlite")
~~~~^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'database.sqlite'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
raise RuntimeError("unable to handle error")
RuntimeError: unable to handle error
```
如果想要设置异常的cause可以使用`from`语法,示例如下所示:
```py
def func():
raise ConnectionError
try:
func()
except ConnectionError as exc:
raise RuntimeError('Failed to open database') from exc
```
上述示例中,`raise ... from exc`直接表明RuntimeError由exc引发。
输出示例如下所示:
```py
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
func()
~~~~^^
File "<stdin>", line 2, in func
ConnectionError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
raise RuntimeError('Failed to open database') from exc
RuntimeError: Failed to open database
```
通过`from None`也可以关闭异常chain示例如下
```py
try:
open('database.sqlite')
except OSError:
raise RuntimeError from None
```
示例如下所示:
```py
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
raise RuntimeError from None
RuntimeError
```
### 用户自定义异常类型
用户如果要自定义异常,可以创建`Exception`类型的子类。
大多数异常类型都以`Error`结尾和standard exceptions的命名规范类似。
### define cleanup action
python支持通过`finally`来定义clean-up action其在所有场景下都会被处理。
```py
try:
raise KeyboardInterrupt
finally:
print('Goodbye, world!')
```
其中finally执行时机如下
- 当抛出异常时如果异常没有被except处理那么异常在finally执行完后再次抛出
- 当except或else中抛出异常时那么异常在finally执行完后被抛出
- 如果在finally中执行了`break, continue, return`等语句,那么异常不会被抛出
- 如果try中执行了`break, continue, return`那么finally会在`break, continue, return`执行之前执行
- 如果finally中执行了return操作那么其return的值将会覆盖try中return的值
finally通常被用于释放资源等操作。
### predefined clean-up action
部分对象定义了对象不在被需要时的clean-up action,无论针对对象的操作是否成功clean-up action都会被执行。
故而,可以通过`with`对该类对象进行使用,并无需手动释放其资源,示例如下:
```py
with open("myfile.txt") as f:
for line in f:
print(line, end="")
```
在上述代码执行完后,文件会自动关闭,即使是在执行过程中遇到异常。
### rasing multi exceptions
在部分时候,可能需要抛出多个异常,此时可以通过`ExceptionGroup`来对exception list进行wrap示例如下
```py
def f():
excs = [OSError('error 1'), SystemError('error 2')]
raise ExceptionGroup('there were problems', excs)
```
#### except*
当使用`except*`时可以选择性处理group中特定类型的异常并将其他异常传递到下游。
```py
def f():
raise ExceptionGroup(
"group1",
[
OSError(1),
SystemError(2),
ExceptionGroup(
"group2",
[
OSError(3),
RecursionError(4)
]
)
]
)
try:
f()
except* OSError as e:
print("There were OSErrors")
except* SystemError as e:
print("There were SystemErrors")
```
### enriching exceptions with notes
当创建异常时,可以通过`add_note(note)`方法来为异常补充信息标准的traceback会按照其被添加的顺序渲染所有的note信息note信息在异常信息之后
```py
try:
raise TypeError('bad type')
except Exception as e: except Exception as e:
print(e) e.add_note('Add some information')
e.add_note('Add some more information')
raise raise
finally:
print("handle correctly")
``` ```
#### 主动抛出异常 其输出如下:
主动抛出异常时,也可使用`raise`关键字
```py ```py
try: Traceback (most recent call last):
raise Exception("fucking Nvidia raised their price!") File "<stdin>", line 2, in <module>
except Exception as e: raise TypeError('bad type')
print(e) TypeError: bad type
finally: Add some information
print("my wallet is empty!") Add some more information
``` ```
## 数据存储
### json.dump
可以通过`json.dump`方法将内容以json的格式存储到文件中
```py ```py
import json def f():
raise OSError('operation failed')
excs = []
for i in range(3):
try:
f()
except Exception as e:
e.add_note(f'Happened in Iteration {i+1}')
excs.append(e)
def save_as_json(data, fd): raise ExceptionGroup('We have some problems', excs)
json.dump(data, fd)
waifu = {
"name": "Touma Kazusa",
"job": "Student",
"gender": "female",
"age": 17
}
is_save_success = True
try:
with open("shiro.json", "w") as shiro_fd:
save_as_json(waifu, shiro_fd)
except Exception as e:
print(e)
is_save_success = False
exit(1)
finally:
if is_save_success:
print("save success!")
``` ```
### json.load 其异常信息如下:
可以通过`json.load`方法读取文件中的json格式内容
```py
import json
def read_as_json(fd):
return json.load(fd)
is_read_success = True
try:
with open("shiro.json", "r") as shiro_fd:
r_obj = read_as_json(shiro_fd)
print(r_obj)
except Exception as e:
print(e)
is_read_success = False
exit(1)
finally:
if is_read_success:
print("read success!")
``` ```
## http api + Exception Group Traceback (most recent call last):
python安装requests包之后可以访问http接口 | File "<stdin>", line 1, in <module>
```py | raise ExceptionGroup('We have some problems', excs)
import math | ExceptionGroup: We have some problems (3 sub-exceptions)
import requests +-+---------------- 1 ----------------
import time | Traceback (most recent call last):
| File "<stdin>", line 3, in <module>
try: | f()
body = requests.get("https://api.m.taobao.com/rest/api3.do", { | ~^^
"api": "mtop.common.getTimestamp" | File "<stdin>", line 2, in f
}).json() | raise OSError('operation failed')
ts = body['data']['t'] | OSError: operation failed
t = time.localtime(math.trunc(int(ts) / 1000)) | Happened in Iteration 1
time_str = time.strftime("%Y-%m-%d %H:%M:%S %z", t) +---------------- 2 ----------------
print(time_str) | Traceback (most recent call last):
except Exception as e: | File "<stdin>", line 3, in <module>
print(e) | f()
raise | ~^^
| File "<stdin>", line 2, in f
| raise OSError('operation failed')
| OSError: operation failed
| Happened in Iteration 2
+---------------- 3 ----------------
| Traceback (most recent call last):
| File "<stdin>", line 3, in <module>
| f()
| ~^^
| File "<stdin>", line 2, in f
| raise OSError('operation failed')
| OSError: operation failed
| Happened in Iteration 3
+------------------------------------
``` ```
## 多线程 ## 多线程