嵌套 Try/Except 或 If/Else - 如何判断使用哪个?

Nested Try/Except or If/Else - How to tell which to use?

我知道已经有关于是否使用 If/Else 或 Try/Except 块的讨论。这样的问题位于:Better to 'try' something and catch the exception or test if its possible first to avoid an exception?

但我想将讨论进一步扩展到 nested try/exceptnested if/elif/else 逻辑块。这是设置...我想编写一个函数,允许用户提供字符串文字、整数或可迭代对象。这是一个高级函数,它将为我编写的其他函数提供某种程度的抽象。我的代码是这样的:

def high_level_func(parameter = None):
    """
    :param parameter: Can accept the string 'All', a single integer, or an iterable such 
        as a range or a list or tuple of ints.
    """
    try:
        if parameter.lower() == 'all'
        # .lower because str input should be case-insensitive
            return str_all_function(parameter) # Only accepts the 
                    # string 'all' - case insensitive
    except AttributeError:
        # if parameter is an int or iter end up here because those types 
        # don't have .lower() methods
        try:
            for para in parameter:
                try:
                    print(int_input_function(parameter))
                except MyException:
                    raise MyException('An iter of something other than ints was '
                                      'provided and cause this error.')
        except TypeError:
            # parameter must be an int because ints aren't iterable and end up here
            return int_input_function(parameter)

在这种情况下,让我们假设我不知道大多数用户会喜欢什么类型的输入(即任何给定用户同样有可能通过 intiter、或字符串 'all'。但我们可以安全地假设用户很可能永远不会传递字符串列表或字符串元组 - 非法 iters)

这样做可以吗?还是检查输入类型并执行 if/elif/else (IEE) 代码块会更好?在您看来,IEE 代码块是否更易于阅读?

备选建议:结合使用 try/except 和 IEE 怎么样? try/except 可能会尝试降低输入,例如,如果它是字符串文字 'all',并且 IEE 将嵌套在 except 块中以检查替代情况(整数或 iter或非法类型)

更一般地说,如果不将函数编写三次并分别进行测试,我如何判断哪种方法最快?

一个更进一步的问题是,如果 Try/Except 平均比 If/Elif/Else 测试快,但我们认为 If/Elif/Else 具有更好的可读性,那么 [= 应该快多少? 41=] 方法是为了保证将可读性从 window 中剔除,还是可读性总是在速度面前占上风?或者这取决于编码器's/team的判断力?

我认为您的输入函数应该负责验证输入,而不是调用它们的函数。之后可以让高级函数一直保持高级,一直trying使用其中一个,直到成功:

def high_level_function(parameter=None):
  try:
    return str_input_function(parameter)
  except ValueError:  # Raised by str_input_function on bad input.
    pass

  try:
    return iter_input_function(parameter)  # MyException now propagates itself.
  except ValueError:  # Raised by iter_input_function on bad input.
    pass

  try:
    return int_input_function(parameter)
  except ValueError:  # Raised by int_input_function on bad input.
    pass

  # This should never be hit:
  raise ValueError("parameter has unsupported type: " + type(parameter).__name__)