题目
给定一个函数 print_avg
,这个函数接收多个关键字参数作为学生的信息,接收多个数字参数作为这个学生多次考试的成绩。
但是,在给定的关键字参数中不一定会存在 student_name
,student_age
,给定的数字参数中也不一定全部是数字,也可能存在字符串,请你自定义两个异常 KeywordNotFound
,NotAllNumbers
。
- 1 在关键字不全时,请你抛出
KeywordNotFound
异常并附加信息:
Incomplete keywords
- 2 当数字参数中不全是数字时,请你抛出
NotAllNumbers
异常并附加信息:
It's not all about numbers
- 3 如果没有异常,请从学生信息中提取出学生的
student_name
,student_age
,然后求出这 个学生 n 次考试的平均成绩Average
(保留两位小数),返回一个字符串,格式如下:
name: student_name, age: student_age, avg: Avera
解析
自定义 KeywordNotFound
,NotAllNumbers
两个异常类。
自定义异常类需要直接或间接的继承自 BaseException
,Exception
类就继承自 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_name
,student_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
- 3 自定义异常类需要直接或间接的继承自
BaseException
,Exception
类就继承自BaseException
,所有内置的,非系统退出异常时从Exception
类派生的,应该从Exception
类派生所有用户定义的异常。