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

Python 嵌套的Try/Except或If/Else-如何判断要使用哪个?,python,if-statement,try-except,Python,If Statement,Try Except,我意识到已经有人讨论过是否使用If/Else或Try/Except块。这个问题在这里: 但是我想把讨论进一步扩展到嵌套的try/except和嵌套的if/elif/else逻辑块。这是设置。。。我想编写一个函数,允许用户提供字符串文字、整数或iterable。这是一个高级函数,它将为我编写的其他函数提供某种程度的抽象。我的代码是这样的: def high_level_func(parameter = None): """ :param parameter: Can accept

我意识到已经有人讨论过是否使用If/Else或Try/Except块。这个问题在这里:

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

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)
在这种情况下,让我们假设我不知道大多数用户会喜欢哪种类型的输入(即,任何给定用户都有可能传递
int
iter
或字符串“all”。但我们可以放心地假设,用户很可能永远不会传递字符串列表或字符串元组-非法
iter
s)

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

替代建议:使用try/except和IEE的组合如何?例如,如果输入是字符串文字“all”,try/except可能会尝试降低输入,IEE将嵌套在
except
块中,以检查替代情况(整数、iter或非法类型)

在更一般的情况下,我如何判断哪种方法是最快的,而不需要三次编写函数并测试每一次


更进一步的问题是,如果Try/Except平均比if/Elif/Else测试快,但我们认为如果/Elif/Else具有更好的可读性,那么Try/Except方法应该快多少才能保证将可读性抛出窗外,或者在速度面前可读性总是占上风?或者这是由编码人员/团队决定的

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

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__)

Python推荐EAFP模型(请求原谅比请求许可更容易),因此在这种情况下,使用try-except将是Python的方式。就个人而言,我会选择非Python方式,并使用if-isinstance(参数,collections.Iterable)为了划分验证,以避免一系列的尝试例外。至于性能,我建议您编写一个更简单的版本,并使用testit模块进行测试。为了补充信息,我确实在100000次迭代中运行了此比较的简化版本,并发现带有isInstance的If/Elif/Else实际上比try/except方法更快od。(不过我没有使用testit模块。)因此,在本例中使用If/Else方法似乎是一种可读性和效率双赢的方法。只是不确定原因。Try/Except方法:1.34000015258789秒/100000循环If/Elif/Else方法:1.188999128112秒/100000循环感谢这一见解。它简单、干净、可读,并且仍然遵循python.K的EAFP方法我对自己过分思考这个问题感到愤怒。我倾向于用python.Grrrr做这件事。没问题!FWIW,我认为你走上了正确的轨道。当我到达
返回
状态时,我应该离开高级函数,对吗?我正在测试我的代码,看起来我正在经历所有的try块,尽管每个try块都有一个return语句,我希望它能成功,但它不能。请确保我期望的和python做的是同一件事。如果它通过了所有内容,它会抛出最后一个异常,您看到了吗?否则,这意味着它已按预期提前返回。抱歉,我发现了。是由缺少int()引起的函数。所以它抛出了一个AttributeError,就像我想要的那样,但是在错误的位置-/