Python 嵌套的Try/Except或If/Else-如何判断要使用哪个?
我意识到已经有人讨论过是否使用If/Else或Try/Except块。这个问题在这里: 但是我想把讨论进一步扩展到嵌套的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
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,就像我想要的那样,但是在错误的位置-/