在python中指定无法访问的代码的pythonic方法是什么,如:
gender = readFromDB(...) # either 'm' or 'f'
if gender == 'm':
greeting = 'Mr.'
elif gender == 'f':
greeting = 'Ms.'
else:
# What should this line say?
答案 0 :(得分:25)
raise ValueError('invalid gender %r' % gender)
答案 1 :(得分:7)
这取决于您对性别的确定程度为'm'
或'f'
。
如果您完全确定,请使用if...else
代替if...elif...else
。只是让每个人都更容易。
但是,如果数据格式错误,您应该提出异常,以便更轻松地进行测试和修复错误。在这种情况下,你可以使用性别中立的问候语,但是对于任何更大的问题,特殊值只会让bug更难找到。
答案 2 :(得分:7)
你可以提出异常:
raise ValueError("Unexpected gender; expected 'm' or 'f', got %s" % gender)
如果您希望数据库只返回“m”或“f”,则使用断言False:
assert False, "Unexpected gender; expected 'm' or 'f', got %s" % gender
答案 3 :(得分:5)
我实际上认为这是个好地方。
class SeriousDesignError(Exception):
pass
所以你可以这样做
if number % 2 == 0:
result = "Even"
elif number % 2 == 1:
result = "Odd"
else:
raise SeriousDesignError()
我认为这是最有意义的错误消息。这种事情只能通过设计错误(或糟糕的维护,这是同一件事)来实现。
答案 4 :(得分:4)
这完全取决于您希望错误发出信号,但在这种情况下我会使用字典:
greetings = {'m': 'Mr.', 'f': 'Ms.'}
gender = readFromDB(...) # either 'm' or 'f'
greeting = greetings[gender]
如果性别既不是m也不是f,这将引发包含意外值的KeyError:
greetings = {'m': 'Mr.', 'f': 'Ms.'}
>>> greetings['W']
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
greetings['W']
KeyError: 'W'
如果您想在邮件中获得更多详细信息,您可以抓住&amp;重新加注:
try:
greeting = greetings[gender]
except KeyError,e:
raise ValueError('Unrecognized gender %s' % gender)
答案 5 :(得分:3)
到目前为止,我通常使用John Fouhy答案的变体 - 但这并不完全正确,正如Ethan指出的那样:
assert gender in ('m', 'f')
if gender == 'm':
greeting = 'Mr.'
else:
greeting = 'Ms.'
使用断言的主要问题是,如果有人使用-O或-OO标志运行您的代码,则断言会被优化掉。正如Ethan在下面指出的那样,这意味着你现在根本没有数据检查。断言是一种开发辅助工具,不应用于生产逻辑。我将养成使用check()函数的习惯 - 这允许干净的调用语法,如断言:
def check(condition, msg=None):
if not condition:
raise ValueError(msg or '')
check(gender in ('m', 'f'))
if gender == 'm':
greeting = 'Mr.'
else:
greeting = 'Ms.'
回到最初的问题,我声称在if / else逻辑之前使用assert()或check()更容易阅读,更安全,更明确:
答案 6 :(得分:2)
我有时会这样做:
if gender == 'm':
greeting = 'Mr.'
else:
assert gender == 'f'
greeting = 'Ms.'
我认为这可以很好地告诉读者代码只有(在这种情况下)两种可能性,以及它们是什么。虽然您可以提出一个比AssertionError更具描述性错误的案例。