java - 异常 + 迭代器结束信号 : why is it bad in Java and normal in Python?

标签 java python exception

我真的很困惑:Java 中的标准方法是仅在“异常”情况下抛出异常,而不用它们来表示迭代器结束。

示例:Effective Java,第 57 项(“仅在异常情况下使用异常”)和 JavaSpecialists newsletter 162 :

Flow control

We should never cause an exception that is otherwise preventable. I have seen code where instead of checking bounds, it is assumed that the data will be correct and then RuntimeExceptions are caught:

Here is an example of bad code (please don't code like this):

public class Antipattern1 {
   public static void main(String[] args) {
     try {
       int i = 0;
       while (true) {
         System.out.println(args[i++]);
       }
     } catch (ArrayIndexOutOfBoundsException e) {
       // we are done
    }
  }
}

而在 Python 中使用这个习语是标准,例如StopIteration :

exception StopIteration

Raised by an iterator‘s next() method to signal that there are no further values. This is derived from Exception rather than StandardError, since this is not considered an error in its normal application.

为什么它对 Java 不利而对 Python 有利?

最佳答案

Python 和 Java 处理异常的方法截然不同。在 Python 中,异常是正常的。查找EAFP (请求原谅比请求许可更容易)在 Python 词汇表中。还要检查什么 Wikipedia不得不说。

StopIteration 只是 EAFP 的一个示例 – 继续并从迭代器中获取下一个内容,如果失败,则处理错误。

如果使用非本地退出使代码更具可读性,则在 Python 中使用异常。你不写支票,如果事情不顺利,你只是处理失败。这绝对没有什么可耻的,事实上它受到鼓励。与 Java 不同。


现在针对 StopIteration 的特定情况:考虑 generator functions .

def generator():
    yield 1
    print('Side effect')
    yield 2

为了支持某种has_next()方法,生成器必须检查下一个值,在2之前触发print > 被要求。必须在迭代器中记住值(或引发的异常)。如果 has_next 被调用两次,则只有第一个会触发副作用。或者下一个值始终可以预先计算,即使不需要。

我发现 Python 的语义——仅在需要下一个值时才计算——最好的选择。

当然 Java 没有可恢复生成器,所以这里很难比较。但有一些轶事证据表明 StopIteration 的泛化能力优于 hasNext()。

关于java - 异常 + 迭代器结束信号 : why is it bad in Java and normal in Python?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7799610/

相关文章:

python - SQLAlchemy - 再次运行自动加载

python - 如何确定AttributeError指的是哪个属性?

ruby-on-rails - ExceptionNotifier 和rescue_from

java - Spring MVC 项目中的 Hibernate Validator

java - 框架内部日志转到 system.out (websphere 7.0)

python - 在 Django 模板中通过 {% url %} 传递命名模式参数

python - 在 wxPython 中调整面板大小时出现图形问题

java - 什么是串行版本 UID?

java - 如何使用 Derby 创建内存数据库表?

java - 获取颜色边界之间所有像素的算法?