我意识到已经讨论过是否使用If / Else或Try / Except块。这样的问题就在这里:Better to 'try' something and catch the exception or test if its possible first to avoid an exception?
但我想将讨论进一步扩展到嵌套 try/except
和嵌套 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)
在这种情况下,让我们假设我不知道大多数用户会喜欢什么类型的输入(即,任何给定用户同样可能通过int
,iter
或者字符串'all'。但是我们可以放心地假设用户很可能永远不会传递字符串列表或字符串元组-illegal iter
s)
这样做还可以,或者我最好检查输入的类型并执行if / elif / else(IEE)代码块?在您看来,IEE代码块是否会更容易阅读?
替代建议:使用try / except和IEE的组合怎么样?例如,try / except可能会尝试降低输入,如果它是字符串文字'all',并且IEE将嵌套在except
块中以检查替代情况(整数或iter或非法类型)
更一般地说,如果不在三个不同时间编写函数并测试每个方法,我如何判断哪种方法最快?
更进一步的问题是,如果Try / Except平均比If / Elif / Else测试更快,但我们认为If / Elif / Else具有更好的可读性,那么Try / Except方法应该更快到多少保证将可读性抛到窗外或在速度面前总是可读性?或者这取决于编码人员/团队的判断?
答案 0 :(得分:2)
我认为你的输入函数应该负责验证输入,而不是调用它们的函数。之后,您可以让高级功能保持高水平,并保持try
使用其中一个,直到成功为止:
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__)