1、不要将可变类型做为函数参数的默认值
举个例子
def apped_number(number,numbers=[]):
numbers.append(number)
print(numbers)
if __name__ == '__main__':
apped_number(1)
apped_number(2)
输出结果:
[1]
[1, 2]
因为python函数的参数默认值只会在函数定义阶段被创建一次,之后不论再调用多少次,函数内拿到的默认值都是同一个对像
如果真手痒痒想用,怎么办呢
def apped_number(number, numbers=None):
if numbers is None:
numbers = []
numbers.append(number)
print(numbers)
if __name__ == '__main__':
apped_number(1)
apped_number(2)
输出结果
[1]
[2]
2、定义“仅限关键字参数”
传说,好的函数,参数应当不超过三个,当然那只是个传说,函数参数多的时候,比比皆是,比如说
def student_info(name,age,sex,height,address):
print(name)
print(age)
print(sex)
print(height)
print(address)
if __name__ == "__main__":
student_info("明明",7,"女",45,"上海")
student_info(name="小三儿",age=8,sex="女",height=47,address="成都")
两种调用方式:
student_info("明明",7,"女",45,"上海") student_info(name="小三儿",age=8,sex="女",height=47,address="成都")明显第二种更可取,因为可读性比较强
那问题来了,就是有一些代码习惯不好的人,就是不想关键字调用,怎么办呢
通过参数列表加“*” 可以解决这个问题 ,“*”号以后的参数必须使用关键字参数模式
def student_info(name, age, *, sex, height, address):
print(name)
print(age)
print(sex)
print(height)
print(address)
if __name__ == "__main__":
student_info("明明", 7, "女", 45, "上海")
不用关键字参数模式会报错
File "D:/practice_code/Practice/function_demo/function_demo03.py", line 19, in <module>
student_info("明明", 7, "女", 45, "上海")
TypeError: student_info() takes 2 positional arguments but 5 were given
3、谨慎返回None值
编程语言中空值随处可见,Go把它叫作nil,Java中叫nulll,python中叫None
我们需要返回None中,应该有三种情况
(1)操作类函数的默认返回值,当某个函数不需要任何返回值时,通常全返回None
def student_info(name, age):
info = [name, age]
if __name__ == "__main__":
print(student_info(name="小三儿", age=8))
输出
None
(2)意料之中的缺失值:比如说数据库中查找用户,能找到返回用户信息,找不到返回None,这个也是合情合理的,比如说re,search这类的函数,找不到匹配对像也会返回None
(3)执行失败的时候代表错误
那这种情况是否可取呢
def insert_student_info(student):
if student:
self.insert_student_to_database(student)
return True
else:
return None
以上代码,如果插入学生信息成功,返回True,否则None,例子可能不恰当,但是要说明一个问题,else分支,其实不需要的是返回一个None,他更想要的是知道为什么插入不成功,因此这种情况建议用异常来代替返回None
4、多返回,早返回:
我们可能遇到过如下情况:
def compare_size(number):
result = ""
if number < 5:
result = f"{number}小于5"
if number > 5 and number < 10:
result = f"{number}大于5小于10"
if number > 10 and number < 50:
result = f"{number}大于10小于50"
if number > 100:
result = f"{number}大于100"
return result
常常会听人说起一条叫“单一出口”的原则,就是说函数应该保证只有一个出口,也就是以上的代码方式
但这种风格可读性会差,因为我在阅读过程中,必须一股脑的把整个函数读完,只要到return才知道他要干啥,所以建议以下方式
def compare_size(number):
if number < 5:
return f"{number}小于5"
if number > 5 and number < 10:
return f"{number}大于5小于10"
if number > 10 and number < 50:
return f"{number}大于10小于50"
if number > 100:
return f"{number}大于100"