这个特殊的例子与Python中的Django有关,但应该适用于支持异常的任何语言:
try: object = ModelClass.objects.get(search=value) except DoesNotExist: pass if object: # do stuff
Django模型类提供了一个简单的方法get,它允许我从数据库中搜索一个且只有一个对象,如果它发现或多或少会引发异常.如果可以使用替代过滤器方法找到零或更多,则返回列表:
objects = ModelClass.objects.filter(search=value) if len(objects) == 1: object = objects[0] # do stuff
我是否过度厌恶异常?对我而言,这个例外似乎有点浪费,据猜测,四分之一到一半的时间将是"特殊的".我更喜欢一个在失败时返回None的函数.我会更好地使用Django的过滤方法并自己处理列表吗?
信不信由你,这实际上是每种语言都有所不同的问题.在Python中,对于语言本身并不例外的事件,会定期抛出异常.因此,我认为"你应该只在异常情况下抛出例外"规则并不十分适用.我认为你在这个论坛上得到的结果将倾向于这个观点,考虑到大量的.Net程序员(参见这个问题)了解更多信息).
至少,我最好不要抓住那些坚持使用Python中的生成器或for循环的人(这两者都涉及在非特殊情况下抛出异常).
围绕使用异常的编程语言存在很大的分歧.
大多数人认为例外应该是例外.在大多数具有例外的语言中,例如,通过异常转移控制比通过程序返回更昂贵.
有一个强烈的少数观点认为,例外只是另一种控制流构造,它们应该便宜.新泽西的标准ML和Objective Caml编译器订阅了该视图.如果你有便宜的例外,你可以用更难以使用其他机制干净地编码的方式编写一些花哨的回溯算法.
我已经看过这个辩论多次重复新的语言设计,而且几乎总是,胜利者决定异常应该是昂贵和罕见的.当你关心表演的时候,你应该考虑到这一点.
线索在名称中 - 例外应该是例外.
如果你总是希望这个项目存在然后使用get
,但如果你认为它不存在合理的时间比例(即它不存在是预期结果而不是特殊结果)那么我建议使用filter
.
所以,当你指出在预期不存在1比2和1比4之间时,我肯定会写一个包装器filter
,因为这绝对不是一个例外情况.