本文是学习朱雷老师《Python工匠》“函数”章节的摘录内容。
在编程语言的世界里,“空值”随处可见,它通常用来表示某个应该存在但是缺失的东西。“空值”在不同语言里均有定义,有不同名字,比如Go把它叫做nil,Java把它叫做null,Python称为None。
在Python中,None是独一无二的存在,因为它有着一种独特的“虚无”含义,所以经常会用做函数的返回值。
当我们需要让函数返回None时,主要是下面3种情况。
(1)操作类函数的默认返回值
当某个操作函数不需要任何返回值时,通常会返回None。与此同时,None也是不带任何return语句的函数的默认返回值。
(2)意料之中的缺失值
有一类函数,它们所做的事情天生就是在尝试,比如从数据库中查找一个用户,在目录中查找一个文件。视条件不同,函数执行后可能有结果,也可能没有结果。而重点在于,对于函数的调用方法说,“没有结果”是意料之中的事情。
(3)在执行失败时代表“错误”
有时候,None也会用作执行失败时的默认值返回值。以下面的函数为例:
def create_user_from_name(username):
if validate_username(username):
return User.from_user(username)
else:
return None
user = create_user_from_name(username)
if user is not None:
user.do_something()
当username通过校验时,函数会返回正常的用户对象,否则返回None。
但是,除了“搜索”“查询”几个场景外,对绝大部分函数而言,返回None并不是一个好的做法,用抛出异常来代替返回None会更合理。如此理解:当函数被调用时,如果无法返回正常结果,就代表出现了意外以外的状况,而“意料之外”正是异常所掌管的领域。
修正上面代码为如下:
class UnableToCreateUser(Exception):
"""当无法创建用户时抛出"""
def create_user_from_name(username):
“”“通过用户名创建一个User实例
:param raises :当无法创建用户时抛出UnableToCreateUser
”“”
if validate_username(username):
return User.from_user(username)
else:
raise UnableToCreateUser(f"无法创建用户:{username}")
try:
user = create_user_from_name(username)
except UnableToCreateUser:
# 此处处理异常
else: # try语句的else的代码块,是未发生异常时执行
user.do_something()
与返回None相比,这种方式要求使用try语句来捕获可能出现的异常。虽然代码多了几行,但是这样做有一个明显的优势:调用方可以从异常对象中获取错误原因——只返回一个None做不到这一点。