简答题第3题:异常处理设计
This commit is contained in:
+27
-3
@@ -57,7 +57,7 @@ logs = [
|
||||
]
|
||||
```
|
||||
|
||||
① 找出所有 level 为 "ERROR" 的日志:
|
||||
找出所有 level 为 "ERROR" 的日志:
|
||||
|
||||
```python
|
||||
error_logs = [log for log in logs if log["level"] == "ERROR"]
|
||||
@@ -65,7 +65,7 @@ error_logs = [log for log in logs if log["level"] == "ERROR"]
|
||||
# {'user': '李四', 'action': 'error', 'level': 'ERROR'}]
|
||||
```
|
||||
|
||||
② 统计每个用户出现几次:
|
||||
统计每个用户出现几次:
|
||||
|
||||
```python
|
||||
user_count = {}
|
||||
@@ -77,6 +77,30 @@ for log in logs:
|
||||
|
||||
也可以用 `collections.Counter` 一行完成:`Counter(log["user"] for log in logs)`。
|
||||
|
||||
③ 为什么不能用 len(logs):`len(logs)` 只返回日志的总条数(这里是 5),它不做任何分类统计。要按用户分别计数,必须用一个 for 循环逐条遍历 logs,取出每条里的 `"user"` 字段,再用字典以用户名为键累加次数。所以需要的是「for 遍历 + 字典累加」这种结构,而不是一个 `len()`。
|
||||
为什么不能用 len(logs):`len(logs)` 只返回日志的总条数(这里是 5),它不做任何分类统计。要按用户分别计数,必须用一个 for 循环逐条遍历 logs,取出每条里的 `"user"` 字段,再用字典以用户名为键累加次数。所以需要的是「for 遍历 + 字典累加」这种结构,而不是一个 `len()`。
|
||||
|
||||
第 3 题:异常处理设计
|
||||
|
||||
函数代码:
|
||||
|
||||
```python
|
||||
def safe_divide(a, b):
|
||||
try:
|
||||
return float(a) / float(b)
|
||||
except (ValueError, ZeroDivisionError):
|
||||
return None
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `float(a)`、`float(b)` 把字符串转成数字,转不了会抛 ValueError;
|
||||
- b 是 "0" 时 `float(b)` 为 0.0,做除法抛 ZeroDivisionError;
|
||||
- 两种异常在同一个 except 里捕获,统一返回 None。
|
||||
|
||||
为什么用 try/except 比先用 if 判断更好:
|
||||
|
||||
- 避免重复转换:用 if 先判断"能不能转",得先试转一次确认、再转一次真正计算,等于转两遍;try/except 直接转,失败就捕获。
|
||||
- 一个 try 块覆盖多个出错点:a 转失败、b 转失败、除数为零,if 要写一串嵌套判断,try 一个块全包住。
|
||||
- 更符合 Python 的 EAFP 风格(先做、出错再补救),比 LBYL(先判断再执行)更简洁健壮。
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user