Python: 抛出异常还是返回None?

4 投票
3 回答
2873 浏览
提问于 2025-04-18 04:15

我想听听大家的意见,看看下面这两段代码中,哪一种方式更符合Python的风格来处理查找。

我正在开发一个用于处理XML文件的包装器。我会加载这个XML文件,解析它,把内容存储在一个字典里,然后通过一个类的方法来访问这些内容。

具体来说,如果给定的查找没有结果,我应该返回None(空值)还是抛出一个(键)错误呢?

我有点困惑,因为有些人建议我抛出一个错误,而不是返回一个空值。他们说这样在更高层次上处理错误会更简单、更清晰。

这是代码的简化版本:

class NoResult(KeyError):
    pass



class Wrapper(object): 
    ....

    self.my_dict = {}

    ....

    get_Entity(self, id):
        if id in self.my_dict:
            value = self.my_dict[id]
            return value
        else:
            return None





class Wrapper(object): 

    ....

    self.my_dict = {}

    ....

    get_Entity(self, id):
        if id in self.my_dict:
            value = self.my_dict[id]
            return value
        else:
            throw NoResult

我非常希望听到你们的想法!

3 个回答

2

好的,这里说的有点笼统,但主要是关于使用你这个库的程序员的期待。如果我在查找一个XML文件,我大概是希望能找到结果的。

假设我是一名懒惰的程序员,不对你返回的结果进行验证就直接使用。如果你给我返回一个特殊的无效值,我的代码会继续运行,但之后会遇到错误,而我可能并不清楚这个错误的根本原因是什么。

相反,如果你在我请求无效值的时候就抛出一个异常,我的程序会立刻崩溃,并且给我一个准确的错误说明,这样我就能知道哪里出了问题。

如果所有程序员都认真验证你库返回的结果,那两种方式都可以,但大多数程序员(可以说是懒惰的程序员)可能不会这样做,因此抛出异常的方式能减少意外和困惑。作为一个库,你肯定不想让用户感到惊讶或困惑,所以我建议使用抛出异常的方式。

不过我也要快速提一下,如果在你的库的工作流程中,进行无效查找是“正常”的操作,那么你可以更合理地期待程序员会进行检查,这样两种方式都可以接受。

记住一个简单的原则:当某个操作确实是例外且让人惊讶的时候,使用异常;否则,你可以根据情况决定,但通常情况下不需要。

4

dict(字典)已经包含了两种行为。一个是当你用 get 方法去查找一个不存在的键时,它会返回 None;另一个是当你直接用 [] 去查找一个不存在的键时,它会报 KeyError 错误。

另外,None 是字典中一个有效的值:

my_dict = {'key': None}
my_dict['key']
# Returns None
4

后者和你对标准Python类型的预期是一致的,可以简化为:

def get_Entity(self, id):
    return self.my_dict[id]

如果id不在self.my_dict里,这段代码会给你抛出一个KeyError错误。出现错误会告诉调用这个函数的地方,字典里原本应该有的东西没有找到。要是悄悄地返回None,就可能会在后面导致一些难以发现的bug(除非你立刻检查if val is None,那样的话其实你也可以用try来处理)。

(另一种写法也可以简化为:

def get_Entity(self, id):
    return self.my_dict.get(id)

)。

撰写回答