习题:4.2 打印学生平均成绩(异常版)

题目

给定一个函数 print_avg,这个函数接收多个关键字参数作为学生的信息,接收多个数字参数作为这个学生多次考试的成绩。
但是,在给定的关键字参数中不一定会存在 student_namestudent_age,给定的数字参数中也不一定全部是数字,也可能存在字符串,请你自定义两个异常 KeywordNotFoundNotAllNumbers

  1. 1 在关键字不全时,请你抛出 KeywordNotFound 异常并附加信息:
Incomplete keywords
  1. 2 当数字参数中不全是数字时,请你抛出 NotAllNumbers 异常并附加信息:
It's not all about numbers
  1. 3 如果没有异常,请从学生信息中提取出学生的 student_namestudent_age,然后求出这       个学生 n 次考试的平均成绩 Average(保留两位小数),返回一个字符串,格式如下:
name: student_name, age: student_age, avg: Avera

 解析

自定义 KeywordNotFoundNotAllNumbers 两个异常类。
自定义异常类需要直接或间接的继承自 BaseExceptionException 类就继承自 BaseException,所有内置的,非系统退出异常时从 Exception 类派生的,应该从 Exception 类派生所有用户定义的异常。

1class KeywordNotFound(Exception):
2    pass
3
4class NotAllNumbers(Exception):
5    pass

因为不知道要接受多少个数字参数,所以我们使用 *args 来将这些非关键字参数打包成元组传入。而对于未知数量的关键字参数,我们使用 **kwargs, 来接收打包成一个字典传入。(args,kwargs 可以是自己定义的形参名)。
所以我们的函数应该定义成:

1def print_avg(*args, **kwargs):
2    pass

这样我们就能接受未知数量的参数了。
接下来是取出学生的 student_namestudent_age,因为不确定是否有这两个属性,我们使用字典的 get() 方法,如果没有的话,获得指定的值 None,如果为 None 说明不存在这两个属性,所以手动抛出异常 KeywordNotFound 异常。

1# kwargs 是一个字典
2name = kwargs.get('student_name', None)
3age = kwargs.get('student_age', None)
4if name is None or age is None:
5    raise KeywordNotFound('Incomplete keywords')

然后是获得学生多次考试的成绩。所有的非关键字参数都被打包到了 args 这个元组中了,但题目中说明,这些参数不全是数字,也可能存在字符串,所以我们需要对这些参数进行检测。将参数中不为整型的放入一个列表中,如果这个列表长度不为 0,说明有非整型参数,手动抛出 NotAllNumbers 异常。
说明

1if len([param for param in args if not isinstance(param, int)]) != 0:
2    raise NotAllNumbers("It's not all about numbers")

如果没有异常就正常计算,然后按照格式返回生成的字符串:

1avg = sum(args) / len(args)
2return f"name: {name}, age: {age}, avg: {avg:.2f}"

题解代码

solution.py

python

1class KeywordNotFound(Exception):
2    pass
3
4
5class NotAllNumbers(Exception):
6    pass
7
8
9def print_avg(*args, **kwargs) -> str:
10    name = kwargs.get('student_name', None)
11    age = kwargs.get('student_age', None)
12    if name is None or age is None:
13        raise KeywordNotFound('Incomplete keywords')
14    if len([param for param in args if not isinstance(param, int)]) != 0:
15        raise NotAllNumbers("It's not all about numbers")
16    avg = sum(args) / len(args)
17    return f"name: {name}, age: {age}, avg: {avg:.2f}"

知识要点

1.1 *args**kwargs

当不知道函数要接收多少个参数时,可以使用 *args,**kwargs。除了 *,** 不可变外,后面的名字可以自己起。
*args 将所有非关键字参数打包成一个元组传入,**kwargs 将所有关键字参数打包成一个字典传入。
1.2  f-string 其中一个用法:

1>>> a = 1
2>>> b = 3
3>>> f'{a / b:.2f}' # 保留两位小数
4>>> 0.33
  1. 3 自定义异常类需要直接或间接的继承自 BaseExceptionException 类就继承自 BaseException,所有内置的,非系统退出异常时从 Exception 类派生的,应该从 Exception 类派生所有用户定义的异常。

猜你喜欢

转载自blog.csdn.net/qq_55858843/article/details/127823989
4.2